PATH=/bin:/usr/bin:/sbin:/usr/sbin
ISU_PKGS_PATH=/opt/isu
+ISU_RUN_PATH=/run/isu
+ISU_CFGS_PATH=/etc/isu
readonly PKG_FILE_NOT_EXIST=100
readonly PKG_INSTALL_ERROR=101
echo " (for development purposes only)"
}
+function print_status_help()
+{
+ if [ -z "${1:-}" ]; then
+ echo ""
+ echo "Usage:"
+ echo -n " $0"
+ fi
+
+ echo " status [-v] [<pkg_name>] - show systemd service status. If no pkg_name given,"
+ echo " show status for all isu services."
+ echo " -v - verbose mode: show sandboxing mechanism, mount files status etc."
+ echo " (output format subject to change, do not parse in scripts)"
+}
+
function print_help()
{
echo ""
echo
echo "commands:"
echo " list - list installed packages"
+ print_status_help x
print_install_help x
print_remove_help x
}
done
}
+function query_systemd_mount_files()
+{
+ local mount_files=$(compgen -G "$ISU_PKGS_PATH/$pkg_name/system-services/*.mount" 2>/dev/null)
+ if [ -z "$mount_files" ]; then
+ is_systemd_mount_file_sandboxing=0
+ return
+ fi
+ # there may be more than one mount file - check all of them, but only in verbose mode
+ if [ "$verbose" == 1 ]; then
+ for m_f in $mount_files; do
+ mount_file_name=$(basename "$m_f")
+ local detailed_mount_state=$(systemctl status "$mount_file_name" 2>&1)
+ grep -q 'Active: active (mounted)' <<< "$detailed_mount_state" || {
+ all_mounts_successful=0
+ break
+ }
+ done
+ fi
+}
+
+function show_sandboxing_method()
+{
+ local no_sandboxing=0
+ if [ "$is_isu_sandboxed" == "0" ] && [ "$is_systemd_mount_file_sandboxing" == "0" ] && [ "$is_systemd_bind_paths" == "0" ]; then
+ no_sandboxing=1
+ fi
+
+ sandboxing_method=""
+ echo -n "sandboxing: "
+ if [ "$is_isu_sandboxed" == "1" ]; then
+ sandboxing_method+="isu-sandbox,"
+ fi
+ if [ "$is_systemd_mount_file_sandboxing" == "1" ]; then
+ if [ "$all_mounts_successful" == "1" ]; then
+ sandboxing_method+="systemd mount files,"
+ else
+ sandboxing_method+="systemd mount files [WARNING: not all mount files active],"
+ fi
+ fi
+ if [ "$is_systemd_bind_paths" == "1" ]; then
+ sandboxing_method+="systemd BindPaths/TemporaryFileSystem"
+ fi
+ if [ "$no_sandboxing" == "1" ]; then
+ sandboxing_method+="no sandboxing"
+ fi
+
+ echo "${sandboxing_method%%,}"
+}
+
+function show_service_status_details()
+{
+ local user_name="$1"
+
+ # query systemd for service state and determine sandboxing method
+ if [ "$user_name" == "root" ]; then
+ local svc_state=$(systemctl show -p SubState --value "$svc_name" 2>&1)
+ else
+ local svc_state=$(su - "$user" -c "systemctl --user show -p SubState --value \"$svc_name\"" 2>&1)
+ fi
+
+ local is_generated=1
+ local is_isu_sandboxed=1
+ local is_systemd_mount_file_sandboxing=1
+ local is_systemd_bind_paths=1
+ local all_mounts_successful=1
+ local is_svc_installed=1
+
+ local detailed_svc_state
+ if [ "$user_name" == "root" ]; then
+ local detailed_svc_state=$(systemctl status "$svc_name" 2>&1)
+ else
+ local detailed_svc_state=$(su - "$user" -c "systemctl --user status \"$svc_name\"" 2>&1)
+ fi
+ grep -qv 'Unit .*\.service could not be found' <<< "$detailed_svc_state" || {
+ echo "Service file: $svc_name.service not found"
+ return
+ }
+
+ if [ "$user_name" == "root" ]; then
+ grep -q 'loaded (/run/systemd/generator' <<< "$detailed_svc_state" || is_generated=0
+ else
+ grep -q 'loaded (/run/user/.*; generated)' <<< "$detailed_svc_state" || is_generated=0
+ fi
+
+ # determine sandboxing method
+ grep -q '/bin/isu-sandbox' <<< "$detailed_svc_state" || is_isu_sandboxed=0
+
+ if [ "$user_name" == "root" ]; then
+ local svc_file=$(systemctl cat "$svc_name" 2>&1)
+ else
+ local svc_file=$(su - "$user" -c "systemctl --user cat \"$svc_name\"" 2>&1)
+ fi
+
+ if [ "$is_isu_sandboxed" == 0 ]; then
+ grep -q '/bin/isu-sandbox' <<< "$svc_file" && is_isu_sandboxed=1
+ fi
+
+ query_systemd_mount_files
+
+ grep -q 'BindPaths\|BindReadOnlyPaths\|TemporaryFileSystem' <<< "$svc_file" || is_systemd_bind_paths=0
+
+ # do not show status for `*.mount.service` file
+ if [ -z "${svc_name##*.mount}" ]; then
+ return
+ fi
+
+ # show isu package info, status and sandboxing method (optional)
+ echo -n "$pkg_name "
+ if [ -n "$version" ]; then
+ echo -n "($version) "
+ fi
+
+ if [ -n "$sys_version" ] && [ "$verbose" == "1" ]; then
+ echo -n "(system package version: $sys_version) "
+ fi
+
+ echo -n "[$svc_name.service] "
+ if [ "$user_name" != "root" ]; then
+ echo -n "[user: $user]: "
+ fi
+
+ echo -n "$svc_state"
+
+ if [ "$verbose" != 1 ]; then
+ echo ""
+ return
+ fi
+
+ if [ "$is_generated" == "1" ]; then
+ echo -n ", "
+ show_sandboxing_method
+ fi
+}
+
+function show_service_status_single()
+{
+ IFS=' ' read -r -a svc_names_arr <<< "$2"
+
+ for i in "${svc_names_arr[@]}"; do
+ if [ -z "$i" ] || [ -z "${i%%service}" ]; then
+ continue
+ fi
+ svc_name=${i%%.service}
+ show_service_status_details "$1"
+ done
+}
+
+function show_system_service_status_single()
+{
+ show_service_status_single "root" "$@"
+}
+
+function show_user_service_status_single()
+{
+ for user in $systemd_users; do
+ show_service_status_single "$user" "$@"
+ done
+}
+
+function isu_status_single()
+{
+ local pkg_name="${1%.service}"
+ local verbose="${2:-0}"
+ local isu_cfg_file=$(cat "$ISU_CFGS_PATH/$pkg_name/isu.cfg" 2>/dev/null)
+ local sys_version=$(grep -e '^version' <<< "$isu_cfg_file" 2>/dev/null | awk -F '=' '{gsub(/[ ]+/,""); print $2}')
+ local isu_run_cfg_file=$(cat "$ISU_RUN_PATH/$pkg_name/isu.cfg" 2>/dev/null)
+ local version=$(grep -e '^version' <<< "$isu_run_cfg_file" 2>/dev/null | awk -F '=' '{gsub(/[ ]+/,""); print $2}')
+ local svc_names=$(grep -e 'system_service\|user_service' <<< "$isu_run_cfg_file" 2>/dev/null | awk -F '=' '{print $2}')
+ local svc_name
+ local is_user_service=1
+
+ svc_names=${svc_names:=${1%.service}}
+ if [ -z "$svc_names" ] || [ -z "$version" ]; then
+ echo "Cannot find the correct isu config file for package: $pkg_name"
+ return
+ fi
+
+ grep -q 'user_service' <<< "$isu_run_cfg_file" || is_user_service=0
+
+ if [ "$is_user_service" == 0 ]; then
+ show_system_service_status_single "$svc_names"
+ else
+ show_user_service_status_single "$svc_names"
+ fi
+}
+
+function query_all_service_statuses()
+{
+ local isu_dirs=$(compgen -G "$ISU_RUN_PATH/*" 2>/dev/null)
+ if [ -z "$isu_dirs" ]; then
+ echo "No isu packages."
+ return
+ fi
+ for pkg_path in $isu_dirs; do
+ local pkg_name=$(basename "$pkg_path")
+ isu_status_single "$pkg_name" "$2"
+ done
+}
+
+function isu_status()
+{
+ local pkg_name="$1"
+ local verbose_flag="$2"
+ local systemd_users=$(ps axo user:100,args | awk '$2 == "/usr/lib/systemd/systemd" && $3 == "--user" { print $1 }')
+
+ case "$1" in
+ all)
+ query_all_service_statuses "$@"
+ ;;
+ *)
+ isu_status_single "$pkg_name" "$verbose_flag"
+ esac
+}
+
function verify_checksum()
{
local pkg_path="$1"
list)
list_pkgs
;;
+ status)
+ verbose=0
+ shift 1
+
+ while getopts "v" arg; do
+ case $arg in
+ v)
+ verbose=1
+ ;;
+ *)
+ print_status_help
+ exit
+ ;;
+ esac
+ done
+
+ shift $((OPTIND-1))
+
+ if [ $# -eq 1 ]; then
+ isu_status "$1" "$verbose"
+ elif [ $# -eq 0 ]; then
+ isu_status "all" "$verbose"
+ else
+ print_status_help
+ fi
+ ;;
install)
force=0
restart_after_install=0