diff --git a/README.md b/README.md index 996ff75..ec68067 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,19 @@ Environment variables are used to control `psadmin-plus` and `psadmin` functiona * Sets the hook script to run before the `stop` command and after the `start` command. * Examples are found in `lib/hooks`. * If not set, default is `false` and no hook is triggered. +* `PS_PSA_OUTPUT` + * `all` - the default - shows normal output like past versions + * `summary` - only show stdout (plus a few special lines from stderr like "x processes started" but reprocessed into stdout. This will help with Rundeck and other tools to keep stderr from being polluted with informational messages. + * `quiet` - hide all output - you can use exit codes from `psa`. On errors, `psa` will display stderr from `psadmin`. +* `PS_PSA_TIMESTAMP` + * `true` - each line will have a timestamp prepended to it - useful with `psa status tux APPDOM` to output the Tuxedo Queue stats to file + * `false` - default +* `PS_PSA_NO_BANNER` + * `true` - do not display the command banner - useful with the `PS_PSA_OUTPUT=quiet` option + * `false` - default +* `PS_PSA_DEBUG` + * `INFO` - default - only display informational messages + * `DEBUG` - display debug output including commands ## Configuration File diff --git a/bin/psa b/bin/psa index d594182..3204bba 100755 --- a/bin/psa +++ b/bin/psa @@ -1,25 +1,27 @@ #!/usr/bin/env ruby begin - require 'psadmin_plus' + require 'psadmin_plus' rescue LoadError - # running directly, not through gem install - require_relative '../lib/psadmin_plus.rb' + # running directly, not through gem install + require_relative '../lib/psadmin_plus.rb' end +include PsadminPlus + # options opts_c = ARGV.shift || "help" opts_t = ARGV.shift || "all" opts_d = ARGV.shift || "all" # Set remaining arguments as environment variables ARGV.each do |arg| - if arg.include? "=" - var = arg.split('=') - ENV[var[0]]=var[1] - puts "Setting environment variable " + var[0] + "=" + var[1] - else - # puts "Skip argument, no valid environment variable found." - end + if arg.include? "=" + var = arg.split('=') + ENV[var[0]]=var[1] + puts "Setting environment variable " + var[0] + "=" + var[1] + else + # puts "Skip argument, no valid environment variable found." + end end commands = opts_c.split(',') @@ -51,14 +53,19 @@ PS_HOOK_POST = ENV['PS_HOOK_POST'] || "false" PS_HOOK_START = ENV['PS_HOOK_START'] || "false" PS_HOOK_STOP = ENV['PS_HOOK_STOP'] || "false" PS_PSA_SUDO = ENV['PS_PSA_SUDO'] || "on" -PS_PSADMIN_PATH = "#{OS_CONST}" == "linux" ? "#{env('PS_HOME')}/bin" : "cmd /c #{env('PS_HOME')}/appserv" +PS_PSADMIN_PATH = "#{OS_CONST}" == "linux" ? "#{env('PS_HOME')}/bin" : "#{ENV['PS_HOME']}/appserv" PS_WIN_SERVICES = ENV['PS_WIN_SERVICES'] || "false" PS_TRAIL_SERVICE = ENV['PS_TRAIL_SERVICE'] || "false" PS_MULTI_HOME = ENV['PS_MULTI_HOME'] || "false" PS_MULTI_DELIMIT = ENV['PS_MULTI_DELIMIT'] || "/" PS_MULTI_PREFIX = ENV['PS_MULTI_PREFIX'].to_i || 0 PS_PARALLEL_BOOT = ENV['PS_PARALLEL_BOOT'] || "false" -PS_PSA_DEBUG = ENV['PS_PSA_DEBUG'] || "false" +PS_PSA_DEBUG = ENV['PS_PSA_DEBUG'] || "INFO" +PS_PSA_TIMESTAMP = ENV['PS_PSA_TIMESTAMP'] || "false" +PS_PSA_OUTPUT = ENV['PS_PSA_OUTPUT'] || "all" # values are "all", "summary", "quiet" +PS_PSA_NO_BANNER = ENV['PS_PSA_NO_BANNER'] || "false" +OS_JOIN = "#{OS_CONST}" == "linux" ? "&&" : ";" +OS_SETENV = "#{OS_CONST}" == "linux" ? "export " : "$env:" # validation # check runtime user @@ -68,7 +75,7 @@ if "#{OS_CONST}" == "linux" then exit end else - # windows - TODO + # nothing end # process @@ -90,6 +97,8 @@ commands.each do |c| case "#{t}" when "app" valid_domains = find_apps + when "tux" + valid_domains = find_apps when "pubsub" valid_domains = find_apps # TODO - find only apps with PUBSUB enabled? when "prcs" diff --git a/lib/psadmin_plus.rb b/lib/psadmin_plus.rb index 75aee26..2e64105 100644 --- a/lib/psadmin_plus.rb +++ b/lib/psadmin_plus.rb @@ -3,640 +3,749 @@ require 'rbconfig' require 'etc' require 'open3' +require 'logger' +require_relative 'runner' + +module PsadminPlus + + @@logger = Logger.new($stdout) + @@logger.level = ENV['PS_PSA_DEBUG'] || "INFO" + @@logger.formatter = proc do |severity, datetime, progname, msg| + date_format = datetime.strftime("%Y-%m-%d %H:%M:%S") + case severity + when "INFO" + green(severity.ljust(5)) + ": #{msg} \n" + when "DEBUG" + blue(severity.ljust(5)) + ": #{msg} \n" + when "ERROR" + red(severity.ljust(5)) + ": #{msg} \n" + end + end -def do_help - puts "Usage: psa [command] " - puts " " - puts "Commands:" - puts " " - puts " help display this help message" - puts " list list domains" - #puts " admin launch psadmin" - puts " summary PS_CFG_HOME summary, no type or domain needed" - puts " status status of the domain" - puts " start hookstart, if enabled, then start the domain" - puts " stop hookstop, if enabled, stop the domain" - puts " restart stop and start the domain" - puts " purge clear domain cache" - puts " reconfigure stop, configure, and start the domain" - puts " bounce stop, flush, purge, configure and start the domain" - puts " kill force stop the domain" - puts " configure configure the domain" - puts " flush clear domain IPC" - puts " " - puts "Types:" - puts " " - puts " app act on application domains" - #puts " pubsub act on PUBSUB group of application domains" - puts " prcs act on process scheduler domains" - puts " web act on web domains" - puts " all, act on web, app, and prcs domains" - puts " " - puts "Domains:" - puts " " - puts " dom act on specific domains" - puts " all, act on all domains" - puts " " - puts "Each parameter type can be enter in a comma separated list " - puts " " -end - -def do_is_runtime_user_nix - result = ENV['USER'] == PS_RUNTIME_USER ? true : false -end - -def do_is_runtime_user_win - result = ENV['USERNAME'] == PS_RUNTIME_USER ? true : false -end - -def env(var) - result = "#{OS_CONST}" == "linux" ? "${#{var}}" : "%#{var}%" -end - -def do_cmd(cmd, print = true, powershell = true) - case "#{OS_CONST}" - when "linux" - if do_is_runtime_user_nix - case "#{PS_PSA_DEBUG}" - when "true" - p "Command: #{cmd}" + def do_help + puts "Usage: psa [command] " + puts " " + puts "Commands:" + puts " " + puts " help display this help message" + puts " list list domains" + puts " summary PS_CFG_HOME summary, no type or domain needed" + puts " status status of the domain" + puts " start hookstart, if enabled, then start the domain" + puts " stop hookstop, if enabled, stop the domain" + puts " restart stop and start the domain" + puts " purge clear domain cache" + puts " reconfigure stop, configure, and start the domain" + puts " bounce stop, flush, purge, configure and start the domain" + puts " kill force stop the domain" + puts " configure configure the domain" + puts " flush clear domain IPC" + puts " " + puts "Types:" + puts " " + puts " app act on application domains" + puts " prcs act on process scheduler domains" + puts " web act on web domains" + puts " all, act on web, app, and prcs domains" + puts " pubsub (status only) PUBSUB group status" + puts " tux (status only) Tuxedo Queue status" + puts " " + puts "Domains:" + puts " " + puts " dom act on specific domains" + puts " all, act on all domains" + puts " " + puts "Each parameter type can be enter in a comma separated list " + puts " " + end + + def colorize(text, color_code); "\e[#{color_code}m#{text}\e[0m"; end + def red(text); colorize(text, 31); end + def green(text); colorize(text, 32); end + def blue(text); colorize(text, 34); end + def info(msg); @@logger.info(msg); end + def debug(msg); @@logger.debug(msg); end + def error(msg); @@logger.error(msg); end + + def os + @os ||= ( + host_os = RbConfig::CONFIG['host_os'] + case host_os + when /mswin|msys|mingw|cygwin|bccwin|wince|emc/ + :windows + when /darwin|mac os/ + :macosx + when /linux/ + :linux + when /solaris|bsd/ + :unix + else + raise Error::WebDriverError, "unknown os: #{host_os.inspect}" + end + ) + end + + def do_is_runtime_user_nix + result = ENV['USER'] == PS_RUNTIME_USER ? true : false + end + + def do_is_runtime_user_win + result = ENV['USERNAME'] == PS_RUNTIME_USER ? true : false + end + + def env(var) + result = "#{OS_CONST}" == "linux" ? "${#{var}}" : "${env:#{var}}" #"%#{var}%" + end + + def do_cmd(cmd:, internal: false, powershell: true) + if internal + output = "off" + else + output = PS_PSA_OUTPUT + end + prefix = "" + suffix = "" + case "#{OS_CONST}" + when "linux" + if do_is_runtime_user_nix + # No prefix/suffix needed + else + if "#{PS_PSA_SUDO}" == "on" + prefix = "sudo su - #{PS_RUNTIME_USER} -c '" + suffix = "'" + else + prefix = "su - #{PS_RUNTIME_USER} -c '" + suffix = "'" + end + end + when "windows" + if powershell + prefix = "powershell -NoProfile -Command \"" + suffix = "\"" + else + prefix = "cmd /c " + suffix = "" end - out = `#{cmd}` else - if "#{PS_PSA_SUDO}" == "on" - case "#{PS_PSA_DEBUG}" - when "true" - p "Command: sudo su - #{PS_RUNTIME_USER} -c '#{cmd}'" + puts "Invalid OS" + end + + debug "Command: #{prefix}#{cmd}#{suffix}" + runner = Runner.new("#{prefix}#{cmd}#{suffix}", realtime = output) + runner.run + + # "internal" is used to bypass output processing for psa internal functions + if internal + debug "internal output" + runner.stdout + else + debug "processing output" + process_output(stdout: runner.stdout, stderr: runner.stderr, success:runner.success?) + end + end + + def process_output(stdout:, stderr:, success:) + if PS_PSA_OUTPUT == "summary" + debug "summary output - stdout" + print_std(std: stdout) + debug "summary output - stderr" + print_std(std: stderr, summary: true) + + end + + case success + when true + debug "command success" + when false + do_output("psadmin returned an error", true) + if PS_PSA_OUTPUT == "summary" || PS_PSA_OUTPUT == "quiet" + print_std(std:stderr, err: true) + end + exit 1 + end + end + + def print_std(std:, err: false, summary: false) + # Standard Output + *lines = std.split(/\n/) + lines.each do | line | + if summary + if line_matches(line) + do_output(line, err) end - out = `sudo su - #{PS_RUNTIME_USER} -c '#{cmd}'` else - print "#{PS_RUNTIME_USER} " - case "#{PS_PSA_DEBUG}" - when "true" - p "Command: su - #{PS_RUNTIME_USER} -c '#{cmd}'" + do_output(line, err) + end + end + end + + def line_matches(line) + debug "matching lines for summary output" + line.include?("processes started") || + line.include?("process started") || + line.include?("processes stopped") + end + + def do_output(line, err = false) + utctime = "" + # Handle Output - Check if timestamps are requested + # - override if parameter is "internal" for internal calls + case PS_PSA_TIMESTAMP + when "true" + utctime = Time.now.strftime("[%Y-%m-%d %H:%M:%S] ") + end + + if !line.empty? + if line != '> ' + if !err + puts (utctime + line).gsub('"', '') + else + puts (utctime + red(line)).gsub('"', '') end - out = `su - #{PS_RUNTIME_USER} -c '#{cmd}'` end end - when "windows" - case powershell - when true - case "#{PS_PSA_DEBUG}" - when "true" - p "Command: powershell -NoProfile -Command \"#{cmd}\"" + end + + def do_cmd_banner(c,t,d) + if PS_PSA_NO_BANNER != "true" + puts "" + puts "===[ #{c} . #{t} . #{d} ]===" + puts "" + end + end + + def do_set_cfg_home(d) + if "#{PS_MULTI_HOME}" != "false" + if PS_MULTI_PREFIX > 0 + h = d.slice(0..PS_MULTI_PREFIX) + else + h = d end - out = `powershell -NoProfile -Command "#{cmd}"` + ENV['PS_CFG_HOME'] = "#{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}#{h}" + end + end + + def find_apps_nix + case "#{PS_MULTI_HOME}" + when "false" + apps = do_cmd(cmd: "find #{env('PS_CFG_HOME')}/appserv/*/psappsrv.ubx 2>/dev/null",internal: true).split(/\n+/) else - case "#{PS_PSA_DEBUG}" - when "true" - p "Command: #{cmd}" - end - out = `#{cmd}` + apps = do_cmd(cmd: "find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/*/psappsrv.ubx 2>/dev/null",internal: true).split(/\n+/) end - else - out = "Invalid OS" + apps.map! {|app| app.split("/")[-2]} end - print ? (puts out) : result = out - out -end -def do_cmd_banner(c,t,d) - puts "" - puts "===[ #{c} . #{t} . #{d} ]===" - puts "" -end + def find_prcss_nix + case "#{PS_MULTI_HOME}" + when "false" + prcss = do_cmd(cmd: "find #{env('PS_CFG_HOME')}/appserv/prcs/*/psprcsrv.ubx 2>/dev/null",internal: true).split(/\n+/) + else + prcss = do_cmd(cmd: "find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/prcs/*/psprcsrv.ubx 2>/dev/null",internal: true).split(/\n+/) + end + prcss.map! {|prcs| prcs.split("/")[-2]} + end -def do_set_cfg_home(d) - if "#{PS_MULTI_HOME}" != "false" - if PS_MULTI_PREFIX > 0 - h = d.slice(0..PS_MULTI_PREFIX) + def find_webs_nix + case "#{PS_MULTI_HOME}" + when "false" + webs = do_cmd(cmd: "find #{env('PS_CFG_HOME')}/webserv/*/piaconfig -maxdepth 0",internal: true).split(/\n+/) else - h = d - end - ENV['PS_CFG_HOME'] = "#{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}#{h}" - end -end - -def find_apps_nix - case "#{PS_MULTI_HOME}" - when "false" - apps = do_cmd("find #{env('PS_CFG_HOME')}/appserv/*/psappsrv.ubx 2>/dev/null",false).split(/\n+/) - else - apps = do_cmd("find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/*/psappsrv.ubx 2>/dev/null",false).split(/\n+/) - end - apps.map! {|app| app.split("/")[-2]} -end - -def find_prcss_nix - case "#{PS_MULTI_HOME}" - when "false" - prcss = do_cmd("find #{env('PS_CFG_HOME')}/appserv/prcs/*/psprcsrv.ubx 2>/dev/null",false).split(/\n+/) - else - prcss = do_cmd("find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/prcs/*/psprcsrv.ubx 2>/dev/null",false).split(/\n+/) - end - prcss.map! {|prcs| prcs.split("/")[-2]} -end - -def find_webs_nix - case "#{PS_MULTI_HOME}" - when "false" - webs = do_cmd("find #{env('PS_CFG_HOME')}/webserv/*/piaconfig -maxdepth 0",false).split(/\n+/) - else - webs = do_cmd("find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/webserv/*/piaconfig -maxdepth 0",false).split(/\n+/) - end - webs.map! {|web| web.split("/")[-2]} -end - -def find_sites_nix(domain) - webs = do_cmd("find ${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/* -maxdepth 0",false).split(/\n+/) - webs.map! {|site| site.split("/")[-1]} -end - -def find_apps_win - case "#{PS_MULTI_HOME}" - when "false" - apps = do_cmd("(get-childitem #{env('PS_CFG_HOME')}/appserv/*/psappsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - else - apps = do_cmd("(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/*/psappsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - end - apps.map! {|app| app.split('\\')[-2]} -end - -def find_prcss_win - case "#{PS_MULTI_HOME}" - when "false" - prcss = do_cmd("(get-childitem #{env('PS_CFG_HOME')}/appserv/prcs/*/psprcsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - else - prcss = do_cmd("(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/prcs/*/psprcsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - end - prcss.map! {|prcs| prcs.split("\\")[-2]} -end - -def find_webs_win - case "#{PS_MULTI_HOME}" - when "false" - webs = do_cmd("(get-childitem #{env('PS_CFG_HOME')}/webserv/*/piaconfig | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - else - webs = do_cmd("(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/webserv/*/piaconfig | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - end - webs.map! {|web| web.split("\\")[-2]} -end - -def find_sites_win(domain) - #TODO - #sites = do_cmd("(get-childitem #{env('PS_CFG_HOME')}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) - #sites.map! {|site| site.split("\\")[-2]} -end - -def find_apps - apps = "#{OS_CONST}" == "linux" ? find_apps_nix : find_apps_win -end - -def find_prcss - prcss = "#{OS_CONST}" == "linux" ? find_prcss_nix : find_prcss_win -end - -def find_webs - webs = "#{OS_CONST}" == "linux" ? find_webs_nix : find_webs_win -end - -def find_sites(domain) - sites = "#{OS_CONST}" == "linux" ? find_sites_nix(domain) : find_sites_win(domain) -end - -def do_util - puts "TODO: util" -end - -def do_admin - do_cmd("#{PS_PSADMIN_PATH}/psadmin") -end - -def do_list - puts "---" - print "hostname: " ; do_cmd('hostname') - print "ps-home: " ; do_cmd('echo ' + env('PS_HOME')) - if PS_MULTI_HOME == "false" - print "ps-cfg-home: " ; do_cmd('echo ' + env('PS_CFG_HOME')) - else - puts "ps-cfg-home base: #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*" - end - puts "" - puts "PS_RUNTIME_USER: #{PS_RUNTIME_USER}" - puts "PS_PSA_SUDO: #{PS_PSA_SUDO}" - puts "PS_HOOK_INTERP: #{PS_HOOK_INTERP}" - puts "PS_HOOK_PRE: #{PS_HOOK_PRE}" - puts "PS_HOOK_POST: #{PS_HOOK_POST}" - puts "PS_HOOK_START: #{PS_HOOK_START}" - puts "PS_HOOK_STOP: #{PS_HOOK_STOP}" - puts "PS_WIN_SERVICES: #{PS_WIN_SERVICES}" - puts "PS_MULTI_HOME: #{PS_MULTI_HOME}" - puts "PS_PARALLEL_BOOT: #{PS_PARALLEL_BOOT}" - puts "PS_PSA_DEBUG: #{PS_PSA_DEBUG}" - puts "" - puts "app:" - find_apps.each do |a| - puts " - #{a}" - end - puts "" - puts "prcs:" - find_prcss.each do |p| - puts " - #{p}" - end - puts "" - puts "web:" - find_webs.each do |w| - puts " - #{w}" - end - puts "" -end - -def do_psadmin_check - # Check to see if psadmin loads correctly - # This will help when used on web servers that don't have Tuxedo - case "#{PS_PSA_DEBUG}" - when "true" - puts "Checking psadmin version to validate configuration:" - check = do_cmd("#{PS_PSADMIN_PATH}/psadmin -v 2>&1",true) - else - check = do_cmd("#{PS_PSADMIN_PATH}/psadmin -v 2>&1",false) - end - if check.include? "error" - # psadmin config is NOT valid - puts "ERROR: psadmin is not configured correctly for this environment!" - puts " Some psadmin-plus actions only work when Tuxedo and psadmin are configured" - false - else - # psadmin config is valid - true - end -end - -def do_summary - if "#{PS_MULTI_HOME}" != "false" - ENV['PS_CFG_HOME'] = "#{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}#{domain}" - end - - do_psadmin_check ? nil : exit - - do_cmd("#{PS_PSADMIN_PATH}/psadmin -envsummary") - #do_status("web","all") -end - -def do_status(type, domain) - case type - when "app" - do_psadmin_check ? nil : return - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c sstatus -d #{domain}") - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c cstatus -d #{domain}") - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c qstatus -d #{domain}") - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c pslist -d #{domain}") - when "pubsub" - ENV['TUXCONFIG'] = "#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG" - do_cmd("echo 'printserver -g PUBSUB' | #{ENV['TUXDIR']}/bin/tmadmin") - when "prcs" - do_psadmin_check ? nil : return - do_cmd("#{PS_PSADMIN_PATH}/psadmin -p status -d #{domain}") - when "web" - # TODO - PIA script status? 1. psadmin, 2. script, 3. lock file, 4. service - #do_psadmin_check ? nil : return - do_cmd("#{PS_PSADMIN_PATH}/psadmin -w status -d #{domain}") - #do_cmd("${PS_CFG_HOME?}/webserv/#{domain}/bin/singleserverStatus.sh") - #if File.exist?("#{ENV['PS_CFG_HOME']}/webserv/#{domain}/servers/PIA/tmp/PIA.lok") - else - puts "Invalid type, see psa help" - end -end - -def do_start(type, domain) - web_service_name = ENV['WEB_SERVICE_NAME'] || "Psft*Pia*#{domain}*" - app_service_name = ENV['APP_SERVICE_NAME'] || "Psft*App*#{domain}*" - prcs_service_name = ENV['PRCS_SERVICE_NAME'] || "Psft*Prcs*#{domain}*" - - case "#{PS_PARALLEL_BOOT}" - when "false" - start_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c boot -d #{domain}" - when "true" - start_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c parallelboot -d #{domain}" - end - start_app_service_cmd = "start-service #{app_service_name}" - start_prcs_cmd = "#{PS_PSADMIN_PATH}/psadmin -p start -d #{domain}" - start_prcs_service_cmd = "start-service #{prcs_service_name}" - start_web_cmd_lnx = "${PS_CFG_HOME?}/webserv/#{domain}/bin/startPIA.sh" - start_web_cmd_win = "#{PS_PSADMIN_PATH}/psadmin -w start -d #{domain}" - start_web_service_cmd = "start-service #{web_service_name}" - - case type - when "app" - case "#{PS_WIN_SERVICES}" - when "true", "tux", "app", "all" - do_cmd(start_app_service_cmd) + webs = do_cmd(cmd: "find #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/webserv/*/piaconfig -maxdepth 0",internal: true).split(/\n+/) + end + webs.map! {|web| web.split("/")[-2]} + end + + def find_sites_nix(domain) + webs = do_cmd(cmd: "find ${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/* -maxdepth 0",internal: true).split(/\n+/) + webs.map! {|site| site.split("/")[-1]} + end + + def find_apps_win + case "#{PS_MULTI_HOME}" + when "false" + apps = do_cmd(cmd: "(get-childitem #{env('PS_CFG_HOME')}/appserv/*/psappsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",internal: true).split(/\n+/) else - do_cmd(start_app_cmd) - case "#{PS_TRAIL_SERVICE}" - when "true" - do_cmd(start_app_service_cmd) - end + apps = do_cmd(cmd: "(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/*/psappsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",internal: true).split(/\n+/) end - do_hookstart("start",type,domain) - when "pubsub" - ENV['TUXCONFIG'] = "#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG" - do_cmd("echo 'boot -g PUBSUB' | #{ENV['TUXDIR']}/bin/tmadmin") - # do_hookstart("start",type,domain) - TODO skip hook for PUBSUB? - when "prcs" - case "#{PS_WIN_SERVICES}" - when "true", "tux", "prcs", "all" - do_cmd(start_prcs_service_cmd) + apps.map! {|app| app.split('\\')[-2]} + end + + def find_prcss_win + case "#{PS_MULTI_HOME}" + when "false" + prcss = do_cmd(cmd: "(get-childitem #{env('PS_CFG_HOME')}/appserv/prcs/*/psprcsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",).split(/\n+/) else - do_cmd(start_prcs_cmd) - case "#{PS_TRAIL_SERVICE}" - when "true" - do_cmd(start_prcs_service_cmd) + prcss = do_cmd(cmd: "(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/appserv/prcs/*/psprcsrv.ubx | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",internal: true).split(/\n+/) + end + prcss.map! {|prcs| prcs.split("\\")[-2]} + end + + def find_webs_win + case "#{PS_MULTI_HOME}" + when "false" + webs = do_cmd(cmd: "(get-childitem #{env('PS_CFG_HOME')}/webserv/*/piaconfig | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",internal: true).split(/\n+/) + else + webs = do_cmd(cmd: "(get-childitem #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*/webserv/*/piaconfig | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",internal: true).split(/\n+/) + end + webs.map! {|web| web.split("\\")[-2]} + end + + def find_sites_win(domain) + #TODO + #sites = do_cmd(cmd: "(get-childitem #{env('PS_CFG_HOME')}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs | Format-Table -property FullName -HideTableHeaders | Out-String).Trim()",false).split(/\n+/) + #sites.map! {|site| site.split("\\")[-2]} + end + + def find_apps + apps = "#{OS_CONST}" == "linux" ? find_apps_nix : find_apps_win + end + + def find_prcss + prcss = "#{OS_CONST}" == "linux" ? find_prcss_nix : find_prcss_win + end + + def find_webs + webs = "#{OS_CONST}" == "linux" ? find_webs_nix : find_webs_win + end + + def find_sites(domain) + sites = "#{OS_CONST}" == "linux" ? find_sites_nix(domain) : find_sites_win(domain) + end + + def do_util + puts "TODO: util" + end + + def do_admin + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin") + end + + def do_list + puts "---" + print "hostname: " ; do_cmd(cmd:'hostname') + print "ps-home: " ; do_cmd(cmd:'echo ' + env('PS_HOME')) + if PS_MULTI_HOME == "false" + print "ps-cfg-home: " ; do_cmd(cmd:'echo ' + env('PS_CFG_HOME')) + else + puts "ps-cfg-home base: #{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}*" + end + puts "" + puts "PS_RUNTIME_USER: #{PS_RUNTIME_USER}" + puts "PS_PSA_SUDO: #{PS_PSA_SUDO}" + puts "PS_HOOK_INTERP: #{PS_HOOK_INTERP}" + puts "PS_HOOK_PRE: #{PS_HOOK_PRE}" + puts "PS_HOOK_POST: #{PS_HOOK_POST}" + puts "PS_HOOK_START: #{PS_HOOK_START}" + puts "PS_HOOK_STOP: #{PS_HOOK_STOP}" + puts "PS_WIN_SERVICES: #{PS_WIN_SERVICES}" + puts "PS_MULTI_HOME: #{PS_MULTI_HOME}" + puts "PS_PARALLEL_BOOT: #{PS_PARALLEL_BOOT}" + puts "PS_PSA_DEBUG: #{PS_PSA_DEBUG}" + puts "PS_PSA_TIMESTAMP: #{PS_PSA_TIMESTAMP}" + puts "PS_PSA_OUTPUT: #{PS_PSA_OUTPUT}" + puts "PS_PSA_NO_BANNER: #{PS_PSA_NO_BANNER}" + puts "" + puts "app:" + find_apps.each do |a| + puts " - #{a}" + end + puts "" + puts "prcs:" + find_prcss.each do |p| + puts " - #{p}" + end + puts "" + puts "web:" + find_webs.each do |w| + puts " - #{w}" + end + puts "" + end + + def do_psadmin_check + # Check to see if psadmin loads correctly + # This will help when used on web servers that don't have Tuxedo + debug "Checking psadmin version to validate configuration:" + check = do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -v 2>&1", internal: true) + if check.include? "error" + # psadmin config is NOT valid + do_output("ERROR: psadmin is not configured correctly for this environment!") + do_output(" Some psadmin-plus actions only work when Tuxedo and psadmin are configured") + false + else + # psadmin config is valid + true + end + end + + def do_summary + if "#{PS_MULTI_HOME}" != "false" + ENV['PS_CFG_HOME'] = "#{PS_MULTI_HOME}#{PS_MULTI_DELIMIT}#{domain}" + end + + do_psadmin_check ? nil : exit + + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -envsummary") + #do_status("web","all") + end + + def do_status(type, domain) + case type + when "app" + do_psadmin_check ? nil : return + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c sstatus -d #{domain}") + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c cstatus -d #{domain}") + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c qstatus -d #{domain}") + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c pslist -d #{domain}") + when "tux" + do_psadmin_check ? nil : return + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "export TUXCONFIG=#{env('PS_CFG_HOME')}/appserv/#{domain}/PSTUXCFG && echo pq | " + env('TUXDIR') + "/bin/tmadmin -r ") + when "windows" + #do_cmd(cmd: "\"set TUXCONFIG=#{ENV['PS_CFG_HOME']}\\appserv\\#{domain}\\PSTUXCFG && echo 'pq' | #{ENV['TUXDIR']}\\bin\\tmadmin -r \"", powershell: false) + end + when "pubsub" + do_psadmin_check ? nil : return + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "export TUXCONFIG=#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG && echo printserver -g PUBSUB | #{env('TUXDIR')}/bin/tmadmin -r") + when "windows" + #do_cmd(cmd: "$env:TUXCONFIG=\"#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG\"; 'printserver -g PUBSUB' | . " + env('TUXDIR') + "/bin/tmadmin -r") end + when "prcs" + do_psadmin_check ? nil : return + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -p status -d #{domain}") + when "web" + # TODO - PIA script status? 1. psadmin, 2. script, 3. lock file, 4. service + #do_psadmin_check ? nil : return + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -w status -d #{domain}") + #do_cmd(cmd: "${PS_CFG_HOME?}/webserv/#{domain}/bin/singleserverStatus.sh") + #if File.exist?("#{ENV['PS_CFG_HOME']}/webserv/#{domain}/servers/PIA/tmp/PIA.lok") + else + puts "Invalid type, see psa help" end - do_hookstart("start",type,domain) - when "web" - case "#{OS_CONST}" - when "linux" - if File.exist?("#{ENV['PS_CFG_HOME']}/webserv/#{domain}/servers/PIA/tmp/PIA.lok") - puts "Domain #{domain} already started" + end + + def do_start(type, domain) + web_service_name = ENV['WEB_SERVICE_NAME'] || "Psft*Pia*#{domain}*" + app_service_name = ENV['APP_SERVICE_NAME'] || "Psft*App*#{domain}*" + prcs_service_name = ENV['PRCS_SERVICE_NAME'] || "Psft*Prcs*#{domain}*" + + case "#{PS_PARALLEL_BOOT}" + when "false" + start_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c boot -d #{domain}" + when "true" + start_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c parallelboot -d #{domain}" + end + start_app_service_cmd = "start-service #{app_service_name}" + start_prcs_cmd = "#{PS_PSADMIN_PATH}/psadmin -p start -d #{domain}" + start_prcs_service_cmd = "start-service #{prcs_service_name}" + start_web_cmd_lnx = "${PS_CFG_HOME?}/webserv/#{domain}/bin/startPIA.sh" + start_web_cmd_win = "#{PS_PSADMIN_PATH}/psadmin -w start -d #{domain}" + start_web_service_cmd = "start-service #{web_service_name}" + + case type + when "app" + case "#{PS_WIN_SERVICES}" + when "true", "tux", "app", "all" + do_cmd(cmd: start_app_service_cmd) else - do_cmd(start_web_cmd_lnx) - sleep 5.0 + do_cmd(cmd: start_app_cmd) + case "#{PS_TRAIL_SERVICE}" + when "true" + do_cmd(cmd: start_app_service_cmd) + end end - when "windows" + do_hookstart("start",type,domain) + when "pubsub" + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "export TUXCONFIG=#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG && echo boot -g PUBSUB | #{env('TUXDIR')}/bin/tmadmin") + when "windows" + #do_cmd(cmd: "$env:TUXCONFIG=\"#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG\"; 'boot -g PUBSUB' | . " + env('TUXDIR') + "/bin/tmadmin -r") + end + when "prcs" case "#{PS_WIN_SERVICES}" - when "true", "web", "all" - do_cmd(start_web_service_cmd) + when "true", "tux", "prcs", "all" + do_cmd(cmd: start_prcs_service_cmd) else - # Run command outside of powershell with 'false' parameter - do_cmd(start_web_cmd_win, true, false) + do_cmd(cmd: start_prcs_cmd) case "#{PS_TRAIL_SERVICE}" + when "true" + do_cmd(cmd: start_prcs_service_cmd) + end + end + do_hookstart("start",type,domain) + when "web" + case "#{OS_CONST}" + when "linux" + if File.exist?("#{ENV['PS_CFG_HOME']}/webserv/#{domain}/servers/PIA/tmp/PIA.lok") + puts "Domain #{domain} already started" + else + do_cmd(cmd: start_web_cmd_lnx) + sleep 5.0 + end + when "windows" + case "#{PS_WIN_SERVICES}" when "true", "web", "all" - do_cmd(start_web_service_cmd) + do_cmd(cmd: start_web_service_cmd) + else + # Run command outside of powershell with 'false' parameter + do_cmd(cmd: start_web_cmd_win, powershell: false) + case "#{PS_TRAIL_SERVICE}" + when "true", "web", "all" + do_cmd(cmd: start_web_service_cmd) + end end end - end - do_hookstart("start",type,domain) - else - puts "Invalid type, see psa help" - end -end - -def do_stop(type, domain) - web_service_name = ENV['WEB_SERVICE_NAME'] || "Psft*Pia*#{domain}*" - app_service_name = ENV['APP_SERVICE_NAME'] || "Psft*App*#{domain}*" - prcs_service_name = ENV['PRCS_SERVICE_NAME'] || "Psft*Prcs*#{domain}*" - - stop_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c shutdown -d #{domain}" - stop_app_service_cmd = "stop-service #{app_service_name}" - stop_prcs_cmd = "#{PS_PSADMIN_PATH}/psadmin -p stop -d #{domain}" - stop_prcs_service_cmd = "stop-service #{prcs_service_name}" - stop_web_cmd_lnx = "${PS_CFG_HOME?}/webserv/#{domain}/bin/stopPIA.sh" - stop_web_cmd_win = "#{PS_PSADMIN_PATH}/psadmin -w shutdown -d #{domain}" - stop_web_service_cmd = "stop-service #{web_service_name}" - - case type - when "app" - do_hookstop("stop",type,domain) - case "#{PS_WIN_SERVICES}" - when "true" - do_cmd(stop_app_service_cmd) + do_hookstart("start",type,domain) else - do_cmd(stop_app_cmd) - case "#{PS_TRAIL_SERVICE}" - when "true" - do_cmd(stop_app_service_cmd) - end + puts "Invalid type, see psa help" end - when "pubsub" - # do_hookstop("stop",type,domain) - TODO skip hook for PUBSUB? - ENV['TUXCONFIG'] = "#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG" - do_cmd("echo 'shutdown -g PUBSUB' | #{ENV['TUXDIR']}/bin/tmadmin") - when "prcs" - do_hookstop("stop",type,domain) - case "#{PS_WIN_SERVICES}" - when "true" - do_cmd(stop_prcs_service_cmd) - else - do_cmd(stop_prcs_cmd) - case "#{PS_TRAIL_SERVICE}" + end + + def do_stop(type, domain) + web_service_name = ENV['WEB_SERVICE_NAME'] || "Psft*Pia*#{domain}*" + app_service_name = ENV['APP_SERVICE_NAME'] || "Psft*App*#{domain}*" + prcs_service_name = ENV['PRCS_SERVICE_NAME'] || "Psft*Prcs*#{domain}*" + + stop_app_cmd = "#{PS_PSADMIN_PATH}/psadmin -c shutdown -d #{domain}" + stop_app_service_cmd = "stop-service #{app_service_name}" + stop_prcs_cmd = "#{PS_PSADMIN_PATH}/psadmin -p stop -d #{domain}" + stop_prcs_service_cmd = "stop-service #{prcs_service_name}" + stop_web_cmd_lnx = "${PS_CFG_HOME?}/webserv/#{domain}/bin/stopPIA.sh" + stop_web_cmd_win = "#{PS_PSADMIN_PATH}/psadmin -w shutdown -d #{domain}" + stop_web_service_cmd = "stop-service #{web_service_name}" + + case type + when "app" + do_hookstop("stop",type,domain) + case "#{PS_WIN_SERVICES}" when "true" - do_cmd(stop_prcs_service_cmd) + do_cmd(cmd: stop_app_service_cmd) + else + do_cmd(cmd: stop_app_cmd) + case "#{PS_TRAIL_SERVICE}" + when "true" + do_cmd(cmd: stop_app_service_cmd) + end end - end - when "web" - do_hookstop("stop",type,domain) - case "#{OS_CONST}" - when "linux" - do_cmd(stop_web_cmd_lnx) - when "windows" + when "pubsub" + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "export TUXCONFIG=#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG && echo stop -g PUBSUB | #{env('TUXDIR')}/bin/tmadmin") + when "windows" + #do_cmd(cmd: "$env:TUXCONFIG=\"#{ENV['PS_CFG_HOME']}/appserv/#{domain}/PSTUXCFG\"; 'boot -g PUBSUB' | . " + env('TUXDIR') + "/bin/tmadmin -r") + end + when "prcs" + do_hookstop("stop",type,domain) case "#{PS_WIN_SERVICES}" when "true" - do_cmd(stop_web_service_cmd) + do_cmd(cmd: stop_prcs_service_cmd) else - do_cmd(stop_web_cmd_win, true, false) + do_cmd(cmd: stop_prcs_cmd) case "#{PS_TRAIL_SERVICE}" when "true" - do_cmd(stop_web_service_cmd) + do_cmd(cmd: stop_prcs_service_cmd) end end + when "web" + do_hookstop("stop",type,domain) + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: stop_web_cmd_lnx) + when "windows" + case "#{PS_WIN_SERVICES}" + when "true" + do_cmd(cmd: stop_web_service_cmd) + else + do_cmd(cmd: stop_web_cmd_win, powershell: false) + case "#{PS_TRAIL_SERVICE}" + when "true" + do_cmd(cmd: stop_web_service_cmd) + end + end + end + else + puts "Invalid type, see psa help" end - else - puts "Invalid type, see psa help" end -end -def do_kill(type, domain) - case type - when "app" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c shutdown! -d #{domain}") - when "prcs" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -p kill -d #{domain}") - when "web" - case "#{OS_CONST}" - when "windows" - do_cmd("(gwmi win32_process | where {$_.Name -eq 'Java.exe'} | where {$_.CommandLine -match '#{domain}'}).ProcessId -ErrorAction SilentlyContinue | % { stop-process $_ -force } -ErrorAction SilentlyContinue") - when "linux" - do_cmd("kill $(ps aux|grep java|grep ${PS_CFG_HOME?}/webserv/#{domain}/piaconfig|awk ' {print $2}')") - end - else - puts "Invalid type, see psa help" - end -end - -def do_configure(type, domain) - case type - when "app" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c configure -d #{domain}") - when "prcs" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -p configure -d #{domain}") - when "web" - do_webprof_reload("#{domain}") - else - puts "Invalid type, see psa help" - end -end - -def do_purge(type, domain) - case type - when "app" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c purge -d #{domain}") - when "prcs" - case "#{OS_CONST}" - when "linux" - do_cmd("rm -rf ${PS_CFG_HOME?}/appserv/prcs/#{domain}/CACHE/*") - when "windows" - do_cmd("Remove-Item $(Get-ChildItem ${env:PS_CFG_HOME}/appserv/prcs/#{domain}/CACHE/* | ?{ $_.PSIsContainer}) -recurse -force -ErrorAction SilentlyContinue".gsub('/','\\')) + def do_kill(type, domain) + case type + when "app" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c shutdown! -d #{domain}") + when "prcs" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -p kill -d #{domain}") + when "web" + case "#{OS_CONST}" + when "windows" + do_cmd(cmd: "(gwmi win32_process | where {$_.Name -eq 'Java.exe'} | where {$_.CommandLine -match '#{domain}'}).ProcessId -ErrorAction SilentlyContinue | % { stop-process $_ -force } -ErrorAction SilentlyContinue") + when "linux" + do_cmd(cmd: "kill $(ps aux|grep java|grep ${PS_CFG_HOME?}/webserv/#{domain}/piaconfig|awk ' {print $2}')") + end + else + puts "Invalid type, see psa help" + end + end + + def do_configure(type, domain) + case type + when "app" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c configure -d #{domain}") + when "prcs" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -p configure -d #{domain}") + when "web" + do_webprof_reload("#{domain}") + else + puts "Invalid type, see psa help" + end + end + + def do_purge(type, domain) + case type + when "app" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c purge -d #{domain}") + when "prcs" + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "rm -rf ${PS_CFG_HOME?}/appserv/prcs/#{domain}/CACHE/*") + when "windows" + do_cmd(cmd: "Remove-Item $(Get-ChildItem ${env:PS_CFG_HOME}/appserv/prcs/#{domain}/CACHE/* | ?{ $_.PSIsContainer}) -recurse -force -ErrorAction SilentlyContinue".gsub('/','\\')) + end + puts "prcs cache purged" + when "web" + case "#{OS_CONST}" + when "linux" + do_cmd(cmd: "rm -rf ${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL*/*/cache*/") + puts "web cache purged" + when "windows" + do_cmd(cmd: "Remove-Item $(Get-ChildItem ${env:PS_CFG_HOME}/webserv/#{domain}/applications/peoplesoft/PORTAL*/*/cache*/ | ?{ $_.PSIsContainer}) -recurse -force -ErrorAction SilentlyContinue".gsub('/','\\')) + end + else + puts "Invalid type, see psa help" + end + end + + def do_flush(type, domain) + case type + when "app" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -c cleanipc -d #{domain}") + when "prcs" + do_cmd(cmd: "#{PS_PSADMIN_PATH}/psadmin -p cleanipc -d #{domain}") + when "web" + return # web flush n/a + else + puts "Invalid type, see psa help" + end + end + + def do_restart(type, domain) + do_stop(type, domain) + do_start(type, domain) + end + + def do_reconfigure(type, domain) + do_stop(type, domain) + do_configure(type, domain) + do_start(type, domain) + end + + def do_bounce(type, domain) + do_stop(type, domain) + do_purge(type, domain) + do_flush(type, domain) + do_configure(type, domain) + do_start(type, domain) + end + + def do_hook(command, type, domain, script) + ENV['PSA_CMD'] = command + ENV['PSA_TYPE'] = type + ENV['PSA_DOMAIN'] = domain + out = `#{PS_HOOK_INTERP} #{script}` + puts out + end + + def do_hookpre(command, type, domain) + if "#{PS_HOOK_PRE}" != "false" + debug "Executing domain pre command hook...\n\n" + do_hook(command, type, domain, PS_HOOK_PRE) + debug "\n...hook done" + end + end + + def do_hookpost(command, type, domain) + if "#{PS_HOOK_POST}" != "false" + debug "Executing domain post command hook...\n\n" + do_hook(command, type, domain, PS_HOOK_POST) + debug "\n...hook done" + end + end + + def do_hookstart(command, type, domain) + if "#{PS_HOOK_START}" != "false" + debug "Executing domain start hook...\n\n" + do_hook(command, type, domain, PS_HOOK_START) + debug "\n...hook done" end - puts "prcs cache purged" - when "web" + end + + def do_hookstop(command, type, domain) + if "#{PS_HOOK_STOP}" != "false" + debug "Executing domain stop hook...\n\n" + do_hook(command, type, domain, PS_HOOK_STOP) + debug "\n...hook done" + end + end + + def do_webprof_reload(domain) + puts "Reloading Web Profiles" + case "#{OS_CONST}" - when "linux" - do_cmd("rm -rf ${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL*/*/cache*/") - puts "web cache purged" - when "windows" - do_cmd("Remove-Item $(Get-ChildItem ${env:PS_CFG_HOME}/webserv/#{domain}/applications/peoplesoft/PORTAL*/*/cache*/ | ?{ $_.PSIsContainer}) -recurse -force -ErrorAction SilentlyContinue".gsub('/','\\')) - end - else - puts "Invalid type, see psa help" - end -end - -def do_flush(type, domain) - case type - when "app" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -c cleanipc -d #{domain}") - when "prcs" - do_cmd("#{PS_PSADMIN_PATH}/psadmin -p cleanipc -d #{domain}") - when "web" - return # web flush n/a - else - puts "Invalid type, see psa help" - end -end - -def do_restart(type, domain) - do_stop(type, domain) - do_start(type, domain) -end - -def do_reconfigure(type, domain) - do_stop(type, domain) - do_configure(type, domain) - do_start(type, domain) -end - -def do_bounce(type, domain) - do_stop(type, domain) - do_purge(type, domain) - do_flush(type, domain) - do_configure(type, domain) - do_start(type, domain) -end - -def do_hook(command, type, domain, script) - ENV['PSA_CMD'] = command - ENV['PSA_TYPE'] = type - ENV['PSA_DOMAIN'] = domain - out = `#{PS_HOOK_INTERP} #{script}` - puts out -end - -def do_hookpre(command, type, domain) - if "#{PS_HOOK_PRE}" != "false" - "#{PS_PSA_DEBUG}" == "true" ? (puts "Executing domain pre command hook...\n\n") : nil - do_hook(command, type, domain, PS_HOOK_PRE) - "#{PS_PSA_DEBUG}" == "true" ? (puts "\n...hook done") : nil - end -end - -def do_hookpost(command, type, domain) - if "#{PS_HOOK_POST}" != "false" - "#{PS_PSA_DEBUG}" == "true" ? (puts "Executing domain post command hook...\n\n") : nil - do_hook(command, type, domain, PS_HOOK_POST) - "#{PS_PSA_DEBUG}" == "true" ? (puts "\n...hook done") : nil - end -end - -def do_hookstart(command, type, domain) - if "#{PS_HOOK_START}" != "false" - "#{PS_PSA_DEBUG}" == "true" ? (puts "Executing domain start hook...\n\n") : nil - do_hook(command, type, domain, PS_HOOK_START) - "#{PS_PSA_DEBUG}" == "true" ? (puts "\n...hook done") : nil - end -end - -def do_hookstop(command, type, domain) - if "#{PS_HOOK_STOP}" != "false" - "#{PS_PSA_DEBUG}" == "true" ? (puts "Executing domain stop hook...\n\n") : nil - do_hook(command, type, domain, PS_HOOK_STOP) - "#{PS_PSA_DEBUG}" == "true" ? (puts "\n...hook done") : nil - end -end - -def do_webprof_reload(domain) - puts "Reloading Web Profiles" - - case "#{OS_CONST}" - when "linux" - "#{PS_PSA_DEBUG}" == "true" ? show_debug = true : show_debug = false - - find_sites(domain).each do |s| - # set vars - url = "${ADMINSERVER_PROTOCOL?}://${ADMINSERVER_HOSTNAME?}:${ADMINSERVER_PORT?}/psp/#{s}/?cmd=login&" - src_env = ". ${PS_CFG_HOME?}/webserv/#{domain}/bin/setEnv.sh" - prop_file = "${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/#{s}/configuration.properties" - - # set reload in config.props - do_cmd("sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=1/g' #{prop_file}",show_debug) - - # source setEnv and ping site - show_debug ? do_cmd("#{src_env} ; curl -s #{url}",show_debug) : do_cmd("#{src_env} ; curl -s -o /dev/null #{url}",show_debug) - - # unset reload in config.props - do_cmd("sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=0/g' #{prop_file}",show_debug) - - # done - puts " - #{s}" - end - when "windows" - puts "Windows support coming soon." - #do_cmd(". #{env('PS_CFG_HOME')}/webserv/#{domain}/bin/setEnv.sh") - - #find_sites.each do |s| - # # set vars - # prop_file = "#{env('PS_CFG_HOME')}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/#{s}}/configuration.properties" - # url = "http://#{PS_PIA_HOST}.#{PS_PIA_DOMAIN}:#{PS_PIA_PORT}/psp/#{s}/?cmd=login&" - # # set reload in config.props - # do_cmd("sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=1/g' #{prop_file}") - # # ping site - # do_cmd("curl -s -o /dev/null '#{url}'") - # # unset reload in config.props - # do_cmd("sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=0/g' #{prop_file}") - # # done - # puts " - #{s}" - #end - else - puts " badOS - #{OS_CONST}" - end - puts "" -end - -def os - @os ||= ( - host_os = RbConfig::CONFIG['host_os'] - case host_os - when /mswin|msys|mingw|cygwin|bccwin|wince|emc/ - :windows - when /darwin|mac os/ - :macosx - when /linux/ - :linux - when /solaris|bsd/ - :unix - else - raise Error::WebDriverError, "unknown os: #{host_os.inspect}" + when "linux" + "#{PS_PSA_DEBUG}" == "DEBUG" ? show_debug = true : show_debug = false + + find_sites(domain).each do |s| + # set vars + url = "${ADMINSERVER_PROTOCOL?}://${ADMINSERVER_HOSTNAME?}:${ADMINSERVER_PORT?}/psp/#{s}/?cmd=login&" + src_env = ". ${PS_CFG_HOME?}/webserv/#{domain}/bin/setEnv.sh" + prop_file = "${PS_CFG_HOME?}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/#{s}/configuration.properties" + + # set reload in config.props + do_cmd(cmd: "sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=1/g' #{prop_file}") + + # source setEnv and ping site + show_debug ? do_cmd(cmd: "#{src_env} ; curl -s #{url}") : do_cmd(cmd: "#{src_env} ; curl -s -o /dev/null #{url}") + + # unset reload in config.props + do_cmd(cmd: "sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=0/g' #{prop_file}") + + # done + puts " - #{s}" end - ) -end + when "windows" + puts "Windows support coming soon." + #do_cmd(cmd: ". #{env('PS_CFG_HOME')}/webserv/#{domain}/bin/setEnv.sh") + + #find_sites.each do |s| + # # set vars + # prop_file = "#{env('PS_CFG_HOME')}/webserv/#{domain}/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/#{s}}/configuration.properties" + # url = "http://#{PS_PIA_HOST}.#{PS_PIA_DOMAIN}:#{PS_PIA_PORT}/psp/#{s}/?cmd=login&" + # # set reload in config.props + # do_cmd(cmd: "sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=1/g' #{prop_file}") + # # ping site + # do_cmd(cmd: "curl -s -o /dev/null '#{url}'") + # # unset reload in config.props + # do_cmd(cmd: "sed -i 's/ReloadWebProfileWithoutRestart=.*/ReloadWebProfileWithoutRestart=0/g' #{prop_file}") + # # done + # puts " - #{s}" + #end + else + puts " badOS - #{OS_CONST}" + end + puts "" + end + +end # End Module \ No newline at end of file diff --git a/lib/runner.rb b/lib/runner.rb new file mode 100644 index 0000000..d9e9f3a --- /dev/null +++ b/lib/runner.rb @@ -0,0 +1,100 @@ +require 'open3' + +class Runner + attr_reader :cmd, :exit_status, :stdout, :stderr, :realtime + + # Run a command, return runner instance + # @param cmd [String,Array] command to execute + def self.run(*cmd) + Runner.new(*cmd).run + end + + # Run a command, raise Runner::Error if it fails + # @param cmd [String,Array] command to execute + # @raise [Runner::Error] + def self.run!(*cmd) + Runner.new(*cmd).run! + end + + # Run a command, return true if it succeeds, false if not + # @param cmd [String,Array] command to execute + # @return [Boolean] + def self.run?(*cmd) + Runner.new(*cmd).run? + end + + Error = Class.new(StandardError) + + # @param cmd [String,Array] command to execute + def initialize(cmd, realtime = false) + @cmd = cmd.is_a?(Array) ? cmd.join(' ') : cmd + @stdout = +'' + @stderr = +'' + @realtime = realtime + @exit_status = nil + end + + # @return [Boolean] success or failure? + def success? + case exit_status + when 0 + true + when 40 # stop an already stopped domain + true + else + false + end + end + + # Run the command, return self + # @return [Runner] + def run + Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr| + until [stdout, stderr].all?(&:eof?) + readable = IO.select([stdout, stderr]) + next unless readable&.first + + readable.first.each do |stream| + data = +'' + # rubocop:disable Lint/HandleExceptions + begin + stream.read_nonblock(1024, data) + rescue EOFError + # ignore, it's expected for read_nonblock to raise EOFError + # when all is read + end + + if stream == stdout + @stdout << data + if @realtime == "all" + $stdout.write(data) + end + else + @stderr << data + if @realtime == "all" + $stderr.write(data) + end + end + end + end + @exit_status = wait_thr.value.exitstatus + end + + self + end + + # Run the command and return stdout, raise if fails + # @return stdout [String] + # @raise [Runner::Error] + def run! + return run.stdout if run.success? + + raise(Error, "psadmin returned an error, exit: %d - stdout: %s / stderr: %s" % [exit_status, stdout, stderr]) + end + + # Run the command and return true if success, false if failure + # @return success [Boolean] + def run? + run.success? + end +end \ No newline at end of file diff --git a/psadmin_plus.gemspec b/psadmin_plus.gemspec index ee61fab..223ab9f 100644 --- a/psadmin_plus.gemspec +++ b/psadmin_plus.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = 'psadmin_plus' - s.version = '2.0.5' - s.date = '2021-04-26' + s.version = '2.0.7' + s.date = '2023-06-07' s.summary = "psadmin plus" s.description = "A psadmin helper tool" s.authors = ["Kyle Benson", "Dan Iverson"] diff --git a/test/test.ps1 b/test/test.ps1 new file mode 100644 index 0000000..55eb54a --- /dev/null +++ b/test/test.ps1 @@ -0,0 +1,38 @@ +# Build the array of commands to test +$commands = @( + "status", + "status tux", + "status pubsub", + "bounce", + "list" +) + +# Build the array of environment variables to set +$variables = @( + "PS_PSA_OUTPUT=all", + "PS_PSA_OUTPUT=summary", + "PS_PSA_TIMESTAMP=true", + "PS_PSA_DEBUG=DEBUG" +) + +# Loop through the array and execute each command +foreach ($cmd in $commands) { + Write-Host "Executing command: $cmd" + + # Set the environment variables for the current command + foreach ($var in $variables) { + $envVar = $var -split "=" + Set-Item -Path "env:$($envVar[0])" -Value $envVar[1] + + Invoke-Expression "bin/psa $cmd" + + # Verify the result of the command + if ($LASTEXITCODE -eq 0) { + Write-Host "Command succeeded" + } else { + Write-Host "Command failed" + } + } + + Write-Host +} \ No newline at end of file diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..8672142 --- /dev/null +++ b/test/test.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Build the array of commands to test +commands=( + "status" + "status tux" + "status pubsub" + "bounce" + "list" +) + +# Build the array of environment variables to set +variables=( + "PS_PSA_OUTPUT=all" + "PS_PSA_OUTPUT=summary" + "PS_PSA_TIMESTAMP=true" + "PS_PSA_DEBUG=DEBUG" +) + +# Loop through the array and execute each command +for cmd in "${commands[@]}" +do + echo "Executing command: $cmd" + + # Set the environment variables for the current command + for var in "${variables[@]}" + do + export "$var" + + eval "bin/psa $cmd" + + # Verify the result of the command + if [ $? -eq 0 ]; then + echo "Test succeeded" + else + echo "Test failed" + fi + done + + echo +done