p4dtg_instance_init.template #1

  • //
  • p4-sdp/
  • r26.1.0.BETA/
  • Server/
  • Unix/
  • p4/
  • common/
  • etc/
  • init.d/
  • p4dtg_instance_init.template
  • View
  • Commits
  • Open Download .zip Download (8 KB)
#!/bin/bash
#==============================================================================
# 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
#------------------------------------------------------------------------------
#
# P4DTG server init script

# p4dtg Init Script.
# chkconfig: - 90 30
# description: P4DTG Start Up Script

export TMP="$P4TMP"
declare OpMode="${1:-usage}"
export OS_INIT_MECHANISM="${OS_INIT_MECHANISM:-Unset}"
declare -i UseSystemd=0
declare ServiceName=
declare RunFile=
declare StopFile=
declare ErrorFile=
declare MovedErrorFile=
declare ForceStartFile=
declare ForceStartMovedFile=
declare -i ForceStart=0

# Load SDP controlled shell environment.
# shellcheck disable=SC1091
source /p4/common/bin/p4_vars REPL_SDP_INSTANCE ||\
   { echo -e "\\nError: Failed to load SDP environment for instance REPL_SDP_INSTANCE.\n"; exit 1; }

# shellcheck disable=SC1091
source "$P4CBIN/ps_functions.sh" ||\
   { echo -e "\\nError: Failed to load SDP ps_functions.sh lib.\n"; exit 1; }

if [[ $(id -u) -eq 0 ]]; then
   exec su - "$OSUSER" -c "$0 $*"
elif [[ $(id -u -n) != "$OSUSER" ]]; then
   echo "$0 can only be run by root or $OSUSER"
   exit 1
fi

cd "$P4DTG_ROOT" ||\
   { echo -e "\\nError: Could not cd to P4DTG_ROOT directory [$P4DTG_ROOT]."; exit 1; }

StopFile="$P4DTG_ROOT/repl/stop-$P4DTG_CFG"
ErrorFile="$P4DTG_ROOT/repl/err-$P4DTG_CFG"
RunFile="${P4DTG_ROOT}/repl/run-${P4DTG_CFG}"

# Determine if systemd is configured for this instance and config.
if [[ -n "$(command -v systemctl)" ]]; then
   ServiceName="${P4DTGBIN##*/}"
   if [[ -n "$(systemctl is-enabled "$ServiceName" 2>/dev/null)" ]]; then
      UseSystemd=1
      MustUseSystemdMsg="\\nError: It appears an attempt was made to start or stop the $ServiceName\\nservice without using systemd. When a systemd unit file is configured, only the\\nsystemd init mechanism can be used to start and stop the service, so that\\nsystemd maintains a more reliable indication of the status of the service. Run\\nas root or as $OSUSER with sudo. For example:\\n\\n\\tsudo systemctl start $ServiceName\\nsudo systemctl stop $ServiceName\\n\\tsystemctl status $ServiceName\\n\\nNote that the 'status' check does not require sudo.\\n\\nThe systemd unit file is:\\n\\n$(systemctl cat "$ServiceName")"
   else
      UseSystemd=0
   fi
fi

ForceStartFile="$P4CCFG/force_start.${SDP_INSTANCE}.p4dtg"

# See how we were called.
case "$OpMode" in
   (prep)
      if [[ -f "$RunFile" ]]; then
         if ! get_pids "$P4DTGBIN" >/dev/null 2>&1; then
            mv -f "$RunFile" "${RunFile}.stale.$(date +%Y%m%d-%H%M%S)" || rm -f "$RunFile"
         fi
      fi

      [[ -e "$StopFile" ]] && rm -f "$StopFile"

      if [[ -e "$ErrorFile" ]]; then
         if [[ -w "$ForceStartFile" ]]; then
            ForceStart=1
            ForceStartMovedFile="${ForceStartFile}.used.$(date +'%Y-%m-%d-%H%M%S')"
            if mv -f "$ForceStartFile" "$ForceStartMovedFile"; then
               echo -e "\\nWarning: The force_start mode is active (one time due to existence of the writable file $ForceStartFile). The P4DTG error file \"$ErrorFile\" will be moved aside and ignored."
            else
               echo -e "\\nWarning: The force_start mode is active due to existence of the file $ForceStartFile. The P4DTG error file \"$ErrorFile\" will be moved aside and ignored."
               echo -e "\\nError: Could not disable force_start mode for subsequent operations. Despite the file being writable, this failed: mv -f \"$ForceStartFile\" \"$ForceStartMovedFile\""
            fi
         elif [[ -e "$ForceStartFile" ]]; then
            ForceStart=1
            echo -e "\\nWarning: The force_start mode is active (persistent due to existence of non-writable file $ForceStartFile). The P4DTG error file \"$ErrorFile\" will be moved aside and ignored."
         elif [[ "${2:-Unset}" == "-f" ]]; then
            ForceStart=1
            echo -e "\\nWarning: The force_start mode is active (due to '-f' option). The P4DTG error file \"$ErrorFile\" will be moved aside and ignored."
         fi

         if [[ "$ForceStart" -eq 1 ]]; then
            MovedErrorFile="$P4DTG_ROOT/repl/MOVED_FILE_err-$(date +'%Y%m%d-%H%M')"
            mv -f "$ErrorFile" "$MovedErrorFile"
            echo -e "\\nWarning: P4DTG Error File detected and moved aside to: $MovedErrorFile\\nStarting anyway due to -f.\\n"
         else
            echo -e "\\nError: Refusing to start because a P4DTG error file was found:\\n\\t$ErrorFile\\nReview this file.\\nTo start P4DTG after reviewing this file, try again with -f which will the error file aside first, i.e.: $0 start -f\\n"
            exit 1
         fi
      fi

      exit 0
   ;;

   (start)
      if [[ "$UseSystemd" -eq 1 && "$OS_INIT_MECHANISM" != "systemd" ]]; then
         echo -e "$MustUseSystemdMsg"
         exit 1
      fi

      p4dtg_pids=$(get_pids "$P4DTGBIN")
      if [[ -n "$p4dtg_pids" ]]; then
         echo -e "Error: ${P4DTGBIN} is already running as pids: $p4dtg_pids."
         exit 1
      fi

      if [[ -f "$RunFile" ]]; then
         # If DTG is truly running, keep the file. If not, it's stale and must be removed.
         if ! get_pids "$P4DTGBIN" >/dev/null 2>&1; then
            mv -f "$RunFile" "${RunFile}.stale.$(date +%Y%m%d-%H%M%S)" || rm -f "$RunFile"
         fi
      fi

      [[ -e "$StopFile" ]] && rm -f "$StopFile"

      if [[ -e "$ErrorFile" ]]; then
         if [[ "${2:-Unset}" == "-f" ]]; then
            MovedErrorFile="$P4DTG_ROOT/repl/MOVED_FILE_err-$(date +'%Y%m%d-%H%M')"
            mv -f "$ErrorFile" "$MovedErrorFile"
            echo -e "\\nWarning: P4DTG Error File detected and moved aside to: $MovedErrorFile\\nStarting anyway due to -f.\\n"
         else
            echo -e "\\nError: Refusing to start because a P4DTG error file was found:\\n\\t$ErrorFile\\nReview this file.\\nTo start P4DTG after reviewing this file, try again with -f which will the error file aside first, i.e.: $0 start -f\\n"
            exit 1
         fi
      fi

      ulimit -c unlimited || true

      # If running with systemd, run the process in the foreground and let systemd handle the
      # process forking. Otherwise, start the service in the background with '&'.
      echo -e "\\nStarting P4DTG with: $P4DTGBIN $P4DTG_CFG $P4DTG_ROOT"
      if [[ "$UseSystemd" -eq 1 ]]; then
         $P4DTGBIN "$P4DTG_CFG" "$P4DTG_ROOT"
      else
         $P4DTGBIN "$P4DTG_CFG" "$P4DTG_ROOT" &
      fi
   ;;

   (stop)
      if [[ "$UseSystemd" -eq 1 && "$OS_INIT_MECHANISM" != "systemd" ]]; then
         echo -e "$MustUseSystemdMsg"
         exit 1
      fi

      p4dtg_pids=$(get_pids "$P4DTGBIN")
      if [[ -z "$p4dtg_pids" ]]; then
         echo -e "Info: ${P4DTGBIN} was NOT running.\\n"
         exit 0
      fi

      echo -e -n "\\nShutting down P4DTG instance P4DTG_CFG ..."
      cd "$P4DTG_ROOT/repl" || { echo -e "\\n\\nError: Could not cd to $P4DTG_ROOT/repl\\n"; exit 1; }
      touch "stop-$P4DTG_CFG" || { echo -e "\\n\\nError: Could not touch stop file: stop-$P4DTG_CFG\\n"; exit 1; }
      p4dtg_pids=$(get_pids "$P4DTGBIN")
      while [[ -n "$p4dtg_pids" ]]; do
         sleep 2
         echo -n "."
         p4dtg_pids=$(get_pids "$P4DTGBIN")
      done
      echo -e "\\n\\nShutdown of P4DTG confirmed.\\n"
   ;;

   (restart)
      $0 stop
      sleep 1
      $0 start
   ;;

   (status)
      p4dtg_pids=$(get_pids "$P4DTGBIN")
      if [[ -n "$p4dtg_pids" ]]; then
         echo "${P4DTGBIN} is running as pids: $p4dtg_pids."
         exit 0
      else
         echo "${P4DTGBIN} is NOT running."
         exit 1
      fi
   ;;

   (*)
      echo -e "\\nUsage: $0 {start [-f] | stop | status | restart}\n"
      exit 1
   ;;
esac

exit 0
# Change User Description Committed
#1 33444 Claude (AI Agent by Anthropic) Initial population of r26.1.0.BETA from main.
//p4-sdp/main/Server/Unix/p4/common/etc/init.d/p4dtg_instance_init.template
#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/etc/init.d/p4dtg_instance_init.template
#3 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.
#2 32480 C. Thomas Tyler Routine merge for SDP from Classic to Streams, done with:

p4 merge -b SDP_Classic_to_Streams
p4 resolve -as

  The automatic-safe resolve handled all files; neither '-am' nor interative resolves were needed.
#1 31397 C. Thomas Tyler Populate -b SDP_Classic_to_Streams -s //guest/perforce_software/sdp/...@31368.
//guest/perforce_software/sdp/dev/Server/Unix/p4/common/etc/init.d/p4dtg_instance_init.template
#10 29100 C. Thomas Tyler Removed requirement for systemd *.service files to have open perms
in *_base scripts and templates.

Removed checks for open perms on *.service files in verify_sdp.sh.

Fixed minor ShellCheck compliance issue.

See also: HI-101: https://swarm.workshop.perforce.com/jobs/HI-101

[Submitting, then re-opening for post-commit final review].
#9 27722 C. Thomas Tyler Refinements to @27712:
* Resolved one out-of-date file (verify_sdp.sh).
* Added missing adoc file for which HTML file had a change (WorkflowEnforcementTriggers.adoc).
* Updated revdate/revnumber in *.adoc files.
* Additional content updates in Server/Unix/p4/common/etc/cron.d/ReadMe.md.
* Bumped version numbers on scripts with Version= def'n.
* Generated HTML, PDF, and doc/gen files:
  - Most HTML and all PDF are generated using Makefiles that call an AsciiDoc utility.
  - HTML for Perl scripts is generated with pod2html.
  - doc/gen/*.man.txt files are generated with .../tools/gen_script_man_pages.sh.

#review-27712
#8 27109 C. Thomas Tyler Refined logic so that if a shutdown is attempted and there is no
server.pid file, the 'fallback/2nd pass/assured shutdown' logic
to do a 'p4 admin stop' files only if a 'p4 info' command can
reach the server. Otherwise, the stop command is silently
ignored.

Refined exit code handling and fixed log interaciton issues.
Fixed issue with systemd status not indicating successful startup.

The systemd unit files now specify the Type as simple rather than
forking, and defer to systemd to handle the forking. When systemd is
used, the -d/--daemonsafe flags are removed from service start commands
for p4p/p4broker/p4d, and for p4dtg the & is removed so the process is
not started in the background. For compatibility with non-systemd systems,
the -d/--daemonsafe flags are still applied when systemd is not in use.

With this change, systemd's concept of whether the service is running should
now be reliable.  If you try to start without using systemd on a system for
which a systemd unit file exists, an error is displayed -- a big, hopefully
useful and informative error message.

#review
#7 21986 C. Thomas Tyler Enhanced P4DTG init script:
* Now removes 'stop' file on startup, eliminating a manual step.
* Provides useful error message if a P4DTG error file is found.
* Provides a '-f' flag to move P4DTG error file aside and start anyway,
  but with a good error message telling the user to review the error
  file first.  (Typically errors are just related to p4d being down.)
* Made 'stop' wait for and confirm shutdown.
* Made 'stop' error out if already stopped.
* Made 'start' error out if already started.
* Made 'restart' robust (by making stop wait for confirmed shutdown).
* Cosmetic and output tweaks.
#6 20491 C. Thomas Tyler Fixed an environment insulation bug in init scripts.

More testing (and thinking) revealed that the only way to truly
provide a guarantee of insulation from user-set defaults in
~perforce/.bashrc (etc.) is to pass SDP_INSTANCE as a parameter to
the *_base scripts, so that the instance name is explicitly passed
into the su/exec call (when run as root).

This change also includes minor cleanup in init scripts and *_base
scripts.
#5 20448 C. Thomas Tyler Fixed env bug seen when running init scripts as root.

Updated *_base scripts and *_init script templates to a new
standard.  Goals:

1. Init scripts that use corresponding *_base scripts are
minimized so that do nothing more than set SDP_INSTANCE and
then call the corresponding *_base script.

2. The 'su' commands always pass $* instead of $1, deferring
all processing to the *_base script.

3. The shell environment is now guaranteeds to have the same
results regardless of whether it is called as 'root' or as
the defined OSUSER.

4. The p4_vars file is always sourced exactly once.  Two
calls to 'source p4_vars' appear in some cases, one
immediatley before the su/exec call, and another after the
after the 'su/exec'.  Only one or the other is sourced.

5. All init scripts have a reasonably consistent usage message.

6. All init scripts accept a 'status' argument.

This change fixes a bug where 'p4broker_N_init status' run as the
'perforce' user would report many pids unrelated to Perforce
if run as root, e.g. doing 'service p4broker_N_init status'.

This also eliminates a potential issue where the 'perforce'
user might source a p4_vars with a default instance in ~/.profile
or ~/.bashrc, thus invalidating the instance specified when the
user ran the init script as root.
#4 20341 C. Thomas Tyler Tweaked all init scripts to default to 'status' (rather than an ugly
syntax error) of the user forgets the start/stop/status parameter,
as was done previosly for the broker init script.

Removed unnecessary 'source' call when calling p4<whateve>_base scripts.

Cleaned up comments.
#3 18852 C. Thomas Tyler Enhanced P4DTG config to be more SDP-ified.
#2 16029 C. Thomas Tyler Routine merge to dev from main using:
p4 merge -b perforce_software-sdp-dev
#1 10638 C. Thomas Tyler Populate perforce_software-sdp-dev.
//guest/perforce_software/sdp/main/Server/Unix/p4/common/etc/init.d/p4dtg_instance_init.template
#1 10148 C. Thomas Tyler Promoted the Perforce Server Deployment Package to The Workshop.