protected ScriptHelper newScript()

in software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java [476:619]


    protected ScriptHelper newScript(Map<String, ?> flags, String phase) {
        if (!Entities.isManagedActive(getEntity()))
            throw new IllegalStateException(getEntity()+" is not currently managed here; cannot create script to run here ("+phase+")");

        if (!Iterables.all(flags.keySet(), StringPredicates.equalToAny(VALID_FLAGS))) {
            throw new IllegalArgumentException("Invalid flags passed: " + flags);
        }

        ScriptHelper s = new ScriptHelper(this, phase+" "+elvis(entity,this));
        if (!groovyTruth(flags.get(NON_STANDARD_LAYOUT))) {
            if (groovyTruth(flags.get(DEBUG))) {
                s.header.prepend("set -x");
            }
            if (INSTALLING.equals(phase)) {
                // mutexId should be global because otherwise package managers will contend with each other
                final String mutexId = "installation lock at host";
                s.useMutex(getMutexes(), mutexId, "installing "+elvis(entity,this));
                s.header.append(
                        "export "+INSTALL_DIR_ENV_VAR+"=\""+getInstallDir()+"\"",
                        "mkdir -p $"+INSTALL_DIR_ENV_VAR,
                        "cd $"+INSTALL_DIR_ENV_VAR,
                        "test -f BROOKLYN && exit 0"
                        );

                if (!groovyTruth(flags.get(INSTALL_INCOMPLETE))) {
                    s.footer.append("date > $INSTALL_DIR/BROOKLYN");
                }
                // don't set vars during install phase, prevent dependency resolution
                s.environmentVariablesReset();
            }
            if (ImmutableSet.of(CUSTOMIZING, LAUNCHING, CHECK_RUNNING, STOPPING, KILLING, RESTARTING).contains(phase)) {
                s.header.append(
                        "export "+INSTALL_DIR_ENV_VAR+"=\""+getInstallDir()+"\"",
                        "export "+RUN_DIR_ENV_VAR+"=\""+getRunDir()+"\"",
                        "mkdir -p $"+RUN_DIR_ENV_VAR,
                        "cd $"+RUN_DIR_ENV_VAR
                        );
            }
        }

        if (ImmutableSet.of(LAUNCHING, RESTARTING).contains(phase)) {
            s.failIfBodyEmpty();
        }
        if (ImmutableSet.of(STOPPING, KILLING).contains(phase)) {
            // stopping and killing allowed to have empty body if pid file set
            if (!groovyTruth(flags.get(USE_PID_FILE)))
                s.failIfBodyEmpty();
        }
        if (ImmutableSet.of(INSTALLING, LAUNCHING).contains(phase)) {
            s.updateTaskAndFailOnNonZeroResultCode();
        }
        if (phase.equalsIgnoreCase(CHECK_RUNNING)) {
            s.setInessential();
            //s.setTransient();
            s.setFlag(SshTool.PROP_CONNECT_TIMEOUT, Duration.TEN_SECONDS.toMilliseconds());
            s.setFlag(SshTool.PROP_SESSION_TIMEOUT, Duration.THIRTY_SECONDS.toMilliseconds());
            s.setFlag(SshTool.PROP_SSH_TRIES, 1);
        }

        if (groovyTruth(flags.get(USE_PID_FILE))) {
            Object usePidFile = flags.get(USE_PID_FILE);
            String pidFile = (usePidFile instanceof CharSequence ? usePidFile : Os.mergePathsUnix(getRunDir(), PID_FILENAME)).toString();
            String processOwner = (String) flags.get(PROCESS_OWNER);
            if (LAUNCHING.equals(phase)) {
                entity.sensors().set(SoftwareProcess.PID_FILE, pidFile);
                s.footer.prepend("echo $! > "+pidFile);
            } else if (CHECK_RUNNING.equals(phase)) {
                // old method, for supplied service, or entity.id
                // "ps aux | grep ${service} | grep \$(cat ${pidFile}) > /dev/null"
                // new way, preferred?
                if (processOwner != null) {
                    s.body.append(
                            bashCommands().sudoAsUser(processOwner, "test -f "+pidFile) + " || exit 1",
                            "ps -p $(" + bashCommands().sudoAsUser(processOwner, "cat "+pidFile) + ")"
                    );
                } else {
                    s.body.append(
                            "test -f "+pidFile+" || exit 1",
                            "ps -p `cat "+pidFile+"`"
                    );
                }
                // no pid, not running; 1 is not running
                s.requireResultCode(Predicates.or(Predicates.equalTo(0), Predicates.equalTo(1)));
            } else if (STOPPING.equals(phase)) {
                String stopCommand = Joiner.on('\n').join("PID=$(cat "+pidFile + ")",
                        "test -n \"$PID\" || exit 0",
                        "SIGTERM_USED=\"\"",
                        "for i in $(seq 1 16); do",
                        "  if ps -p $PID > /dev/null ; then",
                        "     kill $PID",
                        "     echo Attempted to stop PID $PID by sending SIGTERM.",
                        "  else",
                        "     echo Process $PID stopped successfully.",
                        "     SIGTERM_USED=\"true\"",
                        "     break",
                        "  fi",
                        "  sleep 1",
                        "done",
                        "if test -z $SIGTERM_USED; then",
                        "  kill -9 $PID",
                        "  echo Sent SIGKILL to $PID",
                        "fi",
                        "rm -f " + pidFile);
                if (processOwner != null) {
                    s.body.append(bashCommands().sudoAsUser(processOwner, stopCommand));
                } else {
                    s.body.append(stopCommand);
                }
            } else if (KILLING.equals(phase)) {
                if (processOwner != null) {
                    s.body.append(
                            "export PID=$(" + bashCommands().sudoAsUser(processOwner, "cat "+pidFile) + ")",
                            "test -n \"$PID\" || exit 0",
                            bashCommands().sudoAsUser(processOwner, "kill -9 $PID"),
                            bashCommands().sudoAsUser(processOwner, "rm -f "+pidFile)
                    );
                } else {
                    s.body.append(
                            "export PID=$(cat "+pidFile+")",
                            "test -n \"$PID\" || exit 0",
                            "kill -9 $PID",
                            "rm -f "+pidFile
                    );
                }
            } else if (RESTARTING.equals(phase)) {
                if (processOwner != null) {
                    s.footer.prepend(
                            bashCommands().sudoAsUser(processOwner, "test -f "+pidFile) + " || exit 1",
                            "ps -p $(" + bashCommands().sudoAsUser(processOwner, "cat "+pidFile) + ") || exit 1"
                    );
                } else {
                    s.footer.prepend(
                            "test -f "+pidFile+" || exit 1",
                            "ps -p $(cat "+pidFile+") || exit 1"
                    );
                }
                // no pid, not running; no process; can't restart, 1 is not running
            } else {
                log.warn(USE_PID_FILE + ": script option not valid for " + s.summary);
            }
        }

        return s;
    }