service_management.lib #1

  • //
  • p4-sdp/
  • main/
  • Server/
  • Unix/
  • p4/
  • common/
  • lib/
  • service_management.lib
  • View
  • Commits
  • Open Download .zip Download (11 KB)
# shellcheck shell=bash
# Version ID Block (comment-only -- NOT executable). Relies on +k filetype
# modifier. This is a sourced library; a real 'declare' here would clobber
# the sourcing script's own $Version (confirmed: they share global scope).
# show_versions() greps this line's text directly; it is never evaluated.
# VersionID='$Id: //p4-sdp/main/Server/Unix/p4/common/lib/service_management.lib#1 $ $Change: 33433 $'

           
#==============================================================================
# Copyright and license info is available in the LICENSE file included with
# the Server Deployment Package (SDP), and also available online:
# https://workshop.perforce.com/view/p4-sdp/main/LICENSE
#------------------------------------------------------------------------------

#==============================================================================
# This library contains functions related to service management.

#------------------------------------------------------------------------------
# Function: svc_is_up ($server, $instance)
#
# Input:
# $1 - server, one of 'p4d', 'p4p', or 'p4broker'
# $2 - instance, e.g. '1', 'xyz'
#
# Output: None
#
# Return Codes:
# 0: Server is up.
# 1: Server is down.
# 2: Bad usage.
#
# Server up/down status is checked using the appropriate init script.
#------------------------------------------------------------------------------
function svc_is_up () {
   local server="${1:-Unset}"
   local instance="${1:-Unset}"

   case "$server" in
      (p4d)
         "$P4DInitScript" status > /dev/null 2>&1
         return $?
      ;;
      (p4broker)
         "$P4BrokerInitScript" status > /dev/null 2>&1
         return $?
      ;;
      (p4p)
        "$P4ProxyInitScript" status > /dev/null 2>&1
         return $?
      ;;
      (Unset)
         errmsg "Internal Error: svc_is_up(): No server type specified."
         return  2
      ;;
      (*)
         errmsg "Internal Error: svc_is_up(): Unknown server specified: $server"
         return 2
      ;;
   esac
}

#------------------------------------------------------------------------------
# Shutdown p4d using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
#------------------------------------------------------------------------------
function svc_stop_p4d () {
   msg "Shutting down the ${P4DBIN##*/} server."
   local -i maxStopDelay=${SDP_MAX_STOP_DELAY_P4D:-43200}
   local -i stopVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" && ! -r /.dockerenv ]]; then
      serviceName="${P4DBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      sudo systemctl stop "${P4DBIN##*/}" ||\
         bail "Failed to execute: sudo systemctl stop ${P4DBIN##*/}"

      # With systemd, we must independently confirm service stop,
      # waiting if needed.
      stopVerified=0
      i=0; while [[ "$i" -lt "$maxStopDelay" ]]; do
         if svc_is_up p4d; then
            sleep 1
         else
            stopVerified=1
            break
         fi
         i+=1
      done
   else
      "$P4DInitScript" stop
      stopVerified=1
   fi

   if [[ "$stopVerified" -eq 1 ]]; then
      msg "Stopped ${P4DBIN##*/} server."
      return 0
   else
      errmsg "Server ${P4DBIN##*/} did not stop after $maxStopDelay seconds. Tailing $P4LOG:"
      tail "$P4LOG"
      bail "Aborting due to failed p4d stop."
   fi
}

#------------------------------------------------------------------------------
# Shutdown p4broker using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
#------------------------------------------------------------------------------
function svc_stop_p4broker () {
   msg "Shutting down the ${P4BROKERBIN##*/} server."
   local -i maxStopDelay=${SDP_MAX_STOP_DELAY_P4BROKER:-600}
   local -i stopVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" ]]; then
      serviceName="${P4BROKERBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      sudo systemctl stop "${P4BROKERBIN##*/}"
         bail "Failed to execute: sudo systemctl stop ${P4BROKERBIN##*/}"

      # With systemd, we must independently confirm service stop,
      # waiting if needed.
      stopVerified=0
      i=0; while [[ "$i" -lt "$maxStopDelay" ]]; do
         if svc_is_up p4broker; then
            sleep 1
         else
            stopVerified=1
            break
         fi
         i+=1
      done
   else
      "$P4BrokerInitScript" stop
      stopVerified=1
   fi

   if [[ "$stopVerified" -eq 1 ]]; then
      msg "Stopped ${P4BROKERBIN##*/} server."
      return 0
   else
      bail "Server ${P4BROKERBIN##*/} did not stop after $maxStopDelay seconds."
   fi
}

#------------------------------------------------------------------------------
# Shutdown p4p using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
#------------------------------------------------------------------------------
function svc_stop_p4p () {
   msg "Shutting down the ${P4PBIN##*/} server."
   local -i maxStopDelay=${SDP_MAX_STOP_DELAY_P4P:-600}
   local -i stopVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" ]]; then
      serviceName="${P4PBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      sudo systemctl stop "${P4PBIN##*/}"
         bail "Failed to execute: sudo systemctl stop ${P4PBIN##*/}"

      # With systemd, we must independently confirm service stop,
      # waiting if needed.
      stopVerified=0
      i=0; while [[ "$i" -lt "$maxStopDelay" ]]; do
         if svc_is_up p4p; then
            sleep 1
         else
            stopVerified=1
            break
         fi
         i+=1
      done
   else
      "$P4ProxyInitScript" stop
      stopVerified=1
   fi

   if [[ "$stopVerified" -eq 1 ]]; then
      msg "Stopped ${P4PBIN##*/} server."
      return 0
   else
      bail "Server ${P4PBIN##*/} did not stop after $maxStopDelay seconds."
   fi
}

#------------------------------------------------------------------------------
# Start p4d using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
# This is a do-or-die function. It returns success upon successful server
# startup, or else dies.
#------------------------------------------------------------------------------
function svc_start_p4d () {
   msg "Starting the ${P4DBIN##*/} server."
   local -i maxStartDelay=${SDP_MAX_START_DELAY_P4D:-120}
   local -i startVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" && ! -r /.dockerenv ]]; then
      serviceName="${P4DBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      { sudo systemctl start "${P4DBIN##*/}"; } ||\
         bail "Failed to execute: sudo systemctl start ${P4DBIN##*/}"
   else
      "$P4DInitScript" start
   fi

   # Confirm that p4d started, waiting if needed.
   startVerified=0
   i=0; while [[ "$i" -lt "$maxStartDelay" ]]; do
      if svc_is_up p4d; then
         startVerified=1
         break
      else
         sleep 1
      fi
      i+=1
   done

   if [[ "$startVerified" -eq 1 ]]; then
      msg "Server ${P4DBIN##*/} started successfully."
      return 0
   else
      errmsg "Server ${P4DBIN##*/} did not start after $maxStartDelay seconds. Tailing $P4LOG:"
      tail "$P4LOG"
      bail "Aborting due to failed p4d start."
   fi
}

#------------------------------------------------------------------------------
# Start p4broker using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
# This is a do-or-die function. It returns success upon successful server
# startup, or else dies.
#------------------------------------------------------------------------------
function svc_start_p4broker () {
   msg "Starting the ${P4BROKERBIN##*/} server."
   local -i maxStartDelay=${SDP_MAX_START_DELAY_P4BROKER:-60}
   local -i startVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" ]]; then
      serviceName="${P4BROKERBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      { sudo systemctl start "${P4BROKERBIN##*/}"; } ||\
         bail "Failed to execute: sudo systemctl start ${P4BROKERBIN##*/}"
   else
      "$P4BrokerInitScript" start
   fi

   # Confirm that p4broker started, waiting if needed.
   startVerified=0
   i=0; while [[ "$i" -lt "$maxStartDelay" ]]; do
      if svc_is_up p4broker; then
         startVerified=1
         break
      else
         sleep 1
      fi
      i+=1
   done

   if [[ "$startVerified" -eq 1 ]]; then
      msg "Server ${P4BROKERBIN##*/} started successfully."
      return 0
   else
      bail "Server ${P4BROKERBIN##*/} did not start after $maxStartDelay seconds."
   fi
}

#------------------------------------------------------------------------------
# Start p4p using systemd if configured for systemd. Otherwise call the
# underlying init script directly.
#
# This is a do-or-die function. It returns success upon successful server
# startup, or else dies.
#------------------------------------------------------------------------------
function svc_start_p4p () {
   msg "Starting the ${P4PBIN##*/} server."
   local -i maxStartDelay=${SDP_MAX_START_DELAY_P4P:-60}
   local -i startVerified=0
   local -i i=0
   local -i useSystemd=0
   local serviceName=

   if [[ -n "$(command -v systemctl)" ]]; then
      serviceName="${P4PBIN##*/}"
      if [[ -n "$(systemctl is-enabled "$serviceName" 2>/dev/null)" ]]; then
         useSystemd=1
      fi
   fi

   if [[ "$useSystemd" -eq 1 ]]; then
      { sudo systemctl start "${P4PBIN##*/}"; } ||\
         bail "Failed to execute: sudo systemctl start ${P4PBIN##*/}"
   else
      "$P4ProxyInitScript" start
   fi

   # Confirm that p4p started, waiting if needed.
   startVerified=0
   i=0; while [[ "$i" -lt "$maxStartDelay" ]]; do
      if svc_is_up p4p; then
         startVerified=1
         break
      else
         sleep 1
      fi
      i+=1
   done

   if [[ "$startVerified" -eq 1 ]]; then
      msg "Server ${P4PBIN##*/} started successfully."
      return 0
   else
      bail "Server ${P4PBIN##*/} did not start after $maxStartDelay seconds."
   fi
}
# Change User Description Committed
#1 33433 Claude (AI Agent by Anthropic) Copy Up from //p4-sdp/dev into //p4-sdp/main.

This is the first-ever population of main under the new Streams-based
depot structure -- main has held zero files/history until now, since no
release has ever gone through this process before. 463 files, covering
the entire 2026.1 cycle: rebranding (SDP-1379), Secure By Default
(SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version
identification (SDP-1161/SDP-799), the Streams-native release process
redesign itself (Task 5), the opt_perforce_sdp_backup.sh false-error fix,
the P4D 2026.1 test-suite targeting, refreshed P4*.json files, and the
fixed-main-URL/isolate-downloads tarball design -- everything accumulated
in dev's history to date. Isolated paths (ai_dev_support/, Version,
doc/*.html, doc/*.pdf, doc/gen/*.man.txt, doc/gen/sdp_install.cfg,
Unsupported/doc/*.html, Unsupported/doc/*.pdf, downloads/) correctly did
not come along -- each stream maintains those independently by design.

Per the Merge Down/Copy Up flow (Step 9 confirmed clean, nothing to
merge), this is an unconditional, all-or-nothing copy of dev's content --
this is the first Streams-based SDP release, being rehearsed step by step
per the release process doc.

Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic.
//p4-sdp/dev/Server/Unix/p4/common/lib/service_management.lib
#2 33409 Claude (AI Agent by Anthropic) Copy Up from //p4-sdp/dev_rebrand into //p4-sdp/dev.

This is the first promotion of dev_rebrand's work into dev since
dev_rebrand was created (2025-05-24) -- 303 files, covering the entire
2026.1 rebranding effort (SDP-1379), the Secure By Default adaptation
(SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword
version identification (SDP-1161/SDP-799), and the Streams-native release
process redesign (Task 5) done this session, plus everything else
accumulated in dev_rebrand's history before this session.

Per the Merge Down/Copy Up flow, this is intentionally a full,
unconditional blast-replace of dev's content from dev_rebrand -- all
selectivity/care happened in the preceding Merge Down (dev -> dev_rebrand,
changes 33407-33408), which absorbed Robert Cowham's independent dev-side
work first so nothing of his is lost by this Copy Up.

Two files are worth calling out since they might look alarming in
isolation:
- tools/mdcu.sh is deleted -- intentional, retired this session in favor
  of the two direct Streams commands now documented in
  doc/ReleaseProcessOverview.md.
- tools/ReleaseProcessOverview.md is deleted -- this is a stale relic of
  a file move dev_rebrand made back in 2025-05-24 (tools/ -> doc/) that
  was never previously propagated to dev; the current, fully-rewritten
  doc/ReleaseProcessOverview.md is added/updated correctly by this same
  changelist.
#1 33099 C. Thomas Tyler It Begins!
 Potentially the final merge of SDP from Classic to Streams!

This aligns with SDP 2025.2 Patch 1.

p4 merge -b SDP_Classic_to_Streams

p4 resovle -n | wc -l
46

p4 resolve -as

p4 resovle -n | wc -l
0

p4 submit
//guest/perforce_software/sdp/dev/Server/Unix/p4/common/lib/service_management.lib
#1 33011 C. Thomas Tyler Added safety preflight to avoid accidentally running on an existing
server. Running on a server with existing data (as determined by
whether the 'change' counter is 0) now requires using a '-f' (force)
option.

This entailed adding standard command line processing that comes from
the the Coding Standard for Bash. The Coding Standard also provides
more standard logging functionality. Moving to the coding standard
entailed moving away from key dependencies in backup_functions.sh();
e.g. the 'log()' and 'die()' functions were replaced with simpler
'msg()' and 'bail()' -- this greatly increases logging reliability.

Added a new library /p4/common/lib/service_management.lib.

This conversion to the Coding Standard for Bash is a preview of
future changes needed by legacy scripts like live_checkpoint.sh
and daily_checkpoint.sh, etc.

As part of this change, the definition of OFFLINE_DB has been moved
from backup_functions.sh to p4_vars, aligning it with other
fixed-by-standards paths are defined.

Fixes SDP-779.