001/* 002 * #%L 003 * Netarchivesuite - deploy 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.deploy; 024 025import java.io.File; 026import java.io.IOException; 027import java.io.PrintWriter; 028import java.util.HashMap; 029import java.util.Map; 030 031import org.dom4j.Element; 032 033import dk.netarkivet.common.exceptions.IOFailure; 034 035/** 036 * A WindowsMachine is the instance of the abstract machine class, which runs the operating system Windows. This class 037 * only contains the operating system specific functions. 038 */ 039public class WindowsMachine extends Machine { 040 041 /** 042 * The constructor. Starts by initializing the parent abstract class, then sets the operating system dependent 043 * variables. 044 * 045 * @param root The XML root element. 046 * @param parentSettings The Settings to be inherited from the PhysicalLocation, where this machine is placed. 047 * @param param The machine parameters to be inherited from the PhysicalLocation. 048 * @param netarchiveSuiteSource The name of the NetarchiveSuite package file. Must be '.zip'. 049 * @param securityPolicy The security policy file, to be copied into machine directory. 050 * @param dbFile The harvest definition database file. 051 * @param arcdbFile The archive database. 052 * @param resetDir Whether the temporary directory should be reset. 053 * @param externalJarFolder The folder containing the external jar library files. 054 */ 055 public WindowsMachine(Element root, XmlStructure parentSettings, Parameters param, String netarchiveSuiteSource, 056 File slf4JConfig, File securityPolicy, File dbFile, File arcdbFile, boolean resetDir, 057 File externalJarFolder) { 058 super(root, parentSettings, param, netarchiveSuiteSource, slf4JConfig, securityPolicy, dbFile, 059 arcdbFile, resetDir, externalJarFolder); 060 // set operating system 061 operatingSystem = Constants.OPERATING_SYSTEM_WINDOWS_ATTRIBUTE; 062 scriptExtension = Constants.SCRIPT_EXTENSION_WINDOWS; 063 } 064 065 /** 066 * On windows machines console output can cause problems so any uses of ConsoleHandler are 067 * removed. 068 * 069 * @param logProperties the original contents of the logging properties file. 070 * @return logging properties with the ConsoleHandler removed 071 */ 072 /* Is this necessaray with the logback? 073 @Override 074 protected String modifyLogProperties(String logProperties) { 075 String output; 076 // First delete any instances followed by a comma - ie 077 // not as last handler 078 output = logProperties.replaceAll("java.util.logging.ConsoleHandler\\s*,", ""); 079 // Now delete any instances where ConsoleHandler is declared 080 // last 081 output = output.replaceAll(",\\s*java.util.logging.ConsoleHandler", ""); 082 return output; 083 } */ 084 085 /** 086 * Creates the operation system specific installation script for this machine. 087 * <p> 088 * Pseudo code: - echo copying 'NetarchiveSuite.zip' to: 'machine' - scp 'NetarchiveSuite.zip' 'login'@'machine': - 089 * echo unzipping 'NetarchiveSuite.zip' at: 'machine' - ssh 'login'@'machine' 'unzip' 'environmentName' -o 090 * 'NetarchiveSuite.zip - $'create directories'. - echo preparing for copying of settings and scripts - if [ $( ssh 091 * 'login'@'machine' cmd /c if exist 'environmentName'\\conf\\jmxremote.password echo 1 ) ]; then echo Y | ssh 092 * 'login'@'machine' cmd /c cacls 'environmentName'\\conf\\jmxremote.password /P BITARKIV\\'login':F; fi - if [ $( 093 * ssh 'login'@'machine' cmd /c if exist 'environmentName'\\conf\\jmxremote.access echo 1 ) ]; then echo Y | ssh 094 * 'login'@'machine' cmd /c cacls 'environmentName'\\conf\\jmxremote.access /P BITARKIV\\'login':F; fi - echo 095 * copying settings and scripts - scp -r 'machine'/* 'login'@'machine':'environmentName'\\conf\\ - $'apply database 096 * script' - echo make password files readonly * if 'jmxremote-password-path' != 'jmxremote-password-defaultpath' - 097 * ssh 'login'@'machine' move /Y 'jmxremote-password-defaultpath' 'jmxremote-password-path' * if 098 * 'jmxremote-access-path' != 'jmxremote-access-defaultpath' - ssh 'login'@'machine' move /Y 099 * 'jmxremote-access-defaultpath' 'jmxremote-access-path' - echo Y | ssh 'login'@'machine' cmd /c cacls 100 * 'environmentName'\\'jmxremote-password-path' /P BITARKIV\\'login':R - echo Y | ssh 'login'@'machine' cmd /c cacls 101 * 'environmentName'\\'jmxremote-access-path' /P BITARKIV\\'login':R 102 * <p> 103 * variables: 'NetarchiveSuite.zip' = The NetarchiveSuitePackage with '.zip' extension. 'machine' = The machine 104 * name. 'login' = The username for the machine. 'unzip' = The command for unzipping. 'environmentName' = the 105 * environmentName from the configuration file. 106 * <p> 107 * $'...' = call other function. 108 * 109 * @return Operation system specific part of the installscript 110 */ 111 @Override 112 protected String osInstallScript() { 113 StringBuilder res = new StringBuilder(); 114 // - echo copying 'NetarchiveSuite.zip' to: 'machine' 115 res.append(ScriptConstants.ECHO_COPYING + Constants.SPACE); 116 res.append(netarchiveSuiteFileName); 117 res.append(Constants.SPACE + ScriptConstants.TO + Constants.COLON + Constants.SPACE); 118 res.append(hostname); 119 res.append(Constants.NEWLINE); 120 // - scp 'NetarchiveSuite.zip' 'login'@'machine': 121 res.append(ScriptConstants.SCP + Constants.SPACE); 122 res.append(netarchiveSuiteFileName); 123 res.append(Constants.SPACE); 124 res.append(machineUserLogin()); 125 res.append(Constants.COLON); 126 res.append(Constants.NEWLINE); 127 // echo removing old libraries if they exist. 128 res.append(ScriptConstants.ECHO_DELETING_OLD_LIBRARIES); 129 res.append(Constants.NEWLINE); 130 131 // ssh 'login'@'machine' cmd /c if exist 132 // 'environmentName'\\'lib' del /Q 'environmentName'\\'lib' 133 134 res.append(ScriptConstants.SSH + Constants.SPACE); 135 res.append(machineUserLogin()); 136 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.IF 137 + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE); 138 res.append(ScriptConstants.doubleBackslashes(getLocalLibDirPath()) + Constants.SPACE + "DEL /Q" 139 + Constants.SPACE); 140 res.append(ScriptConstants.doubleBackslashes(getLocalLibDirPath())); 141 res.append(Constants.SPACE + Constants.NEWLINE); 142 143 // - echo unzipping 'NetarchiveSuite.zip' at: 'machine' 144 res.append(ScriptConstants.ECHO_UNZIPPING + Constants.SPACE); 145 res.append(netarchiveSuiteFileName); 146 res.append(Constants.SPACE + ScriptConstants.AT + Constants.COLON + Constants.SPACE); 147 res.append(hostname); 148 res.append(Constants.NEWLINE); 149 // - ssh 'login'@'machine' 'unzip' 'environmentName' -o 150 // 'NetarchiveSuite.zip 151 res.append(ScriptConstants.SSH + Constants.SPACE); 152 res.append(machineUserLogin()); 153 res.append(Constants.SPACE + ScriptConstants.WINDOWS_UNZIP_COMMAND + Constants.SPACE); 154 res.append(getEnvironmentName()); 155 res.append(Constants.SPACE + ScriptConstants.SCRIPT_OUTPUT + Constants.SPACE); 156 res.append(netarchiveSuiteFileName); 157 res.append(Constants.NEWLINE); 158 // - $'create directories'. 159 res.append(osInstallScriptCreateDir()); 160 // - echo preparing for copying of settings and scripts 161 res.append(ScriptConstants.ECHO_PREPARING_FOR_COPY); 162 res.append(Constants.NEWLINE); 163 // - if [ $( ssh 'login'@'machine' cmd /c if exist 164 // 'environmentName'\\'jmxremote.password' echo 1 ) ]; then echo Y 165 // | ssh 'login'@'machine' cmd /c cacls 166 // 'environmentName'\\'jmxremote.password' /P BITARKIV\\'login':F; fi 167 res.append(ScriptConstants.IF + Constants.SPACE + Constants.SQUARE_BRACKET_BEGIN + Constants.SPACE 168 + Constants.DOLLAR_SIGN + Constants.BRACKET_BEGIN + Constants.SPACE + ScriptConstants.SSH 169 + Constants.SPACE); 170 res.append(machineUserLogin()); 171 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.IF 172 + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE); 173 res.append(ScriptConstants.doubleBackslashes(getLocalConfDirPath())); 174 res.append(Constants.JMX_PASSWORD_FILE_NAME); 175 res.append(Constants.SPACE + ScriptConstants.ECHO_ONE); 176 res.append(Constants.SPACE + Constants.BRACKET_END + Constants.SPACE + Constants.SQUARE_BRACKET_END 177 + Constants.SEMICOLON + Constants.SPACE + ScriptConstants.THEN + Constants.SPACE); 178 res.append(ScriptConstants.ECHO_Y + Constants.SPACE + Constants.SEPARATOR + Constants.SPACE 179 + ScriptConstants.SSH + Constants.SPACE); 180 res.append(machineUserLogin()); 181 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.CACLS 182 + Constants.SPACE); 183 res.append(ScriptConstants.doubleBackslashes(getLocalConfDirPath())); 184 res.append(Constants.JMX_PASSWORD_FILE_NAME + Constants.SPACE + ScriptConstants.SLASH_P + Constants.SPACE 185 + ScriptConstants.BITARKIV_BACKSLASH_BACKSLASH); 186 res.append(machineParameters.getMachineUserName().getText().trim()); 187 res.append(ScriptConstants.COLON_F + Constants.SEMICOLON + Constants.SPACE + ScriptConstants.FI 188 + Constants.SEMICOLON); 189 res.append(Constants.NEWLINE); 190 // - if [ $( ssh 'login'@'machine' cmd /c if exist 191 // 'environmentName'\\'jmxremote.access' echo 1 ) ]; then echo Y 192 // | ssh 'login'@'machine' cmd /c cacls 193 // 'environmentName'\\'jmxremote.access' /P BITARKIV\\'login':F; fi 194 res.append(ScriptConstants.IF + Constants.SPACE + Constants.SQUARE_BRACKET_BEGIN + Constants.SPACE 195 + Constants.DOLLAR_SIGN + Constants.BRACKET_BEGIN + Constants.SPACE + ScriptConstants.SSH 196 + Constants.SPACE); 197 res.append(machineUserLogin()); 198 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.IF 199 + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE); 200 res.append(ScriptConstants.doubleBackslashes(getLocalConfDirPath())); 201 res.append(Constants.JMX_ACCESS_FILE_NAME); 202 res.append(Constants.SPACE + ScriptConstants.ECHO_ONE); 203 res.append(Constants.SPACE + Constants.BRACKET_END + Constants.SPACE + Constants.SQUARE_BRACKET_END 204 + Constants.SEMICOLON + Constants.SPACE + ScriptConstants.THEN + Constants.SPACE 205 + ScriptConstants.ECHO_Y + Constants.SPACE); 206 res.append(Constants.SEPARATOR + Constants.SPACE + ScriptConstants.SSH + Constants.SPACE); 207 res.append(machineUserLogin()); 208 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.CACLS 209 + Constants.SPACE); 210 res.append(ScriptConstants.doubleBackslashes(getLocalConfDirPath())); 211 res.append(Constants.JMX_ACCESS_FILE_NAME + Constants.SPACE + ScriptConstants.SLASH_P + Constants.SPACE 212 + ScriptConstants.BITARKIV_BACKSLASH_BACKSLASH); 213 res.append(machineParameters.getMachineUserName().getText().trim()); 214 res.append(ScriptConstants.COLON_F + Constants.SEMICOLON + Constants.SPACE + ScriptConstants.FI 215 + Constants.SEMICOLON); 216 res.append(Constants.NEWLINE); 217 // - echo copying settings and scripts 218 res.append(ScriptConstants.ECHO_COPY_SETTINGS_AND_SCRIPTS); 219 res.append(Constants.NEWLINE); 220 // - scp -r 'machine'/* 'login'@'machine':'environmentName'\\conf\\ 221 res.append(ScriptConstants.SCP + Constants.SPACE + ScriptConstants.DASH_R + Constants.SPACE); 222 res.append(hostname); 223 res.append(Constants.SLASH + Constants.STAR + Constants.SPACE); 224 res.append(machineUserLogin()); 225 res.append(Constants.COLON); 226 res.append(ScriptConstants.doubleBackslashes(getLocalConfDirPath())); 227 res.append(Constants.NEWLINE); 228 // INSTALL EXTERNAL JAR FILES. 229 res.append(osInstallExternalJarFiles()); 230 // APPLY DATABASE! 231 res.append(osInstallDatabase()); 232 // APPLY ARCHIVE DATABASE! 233 res.append(osInstallArchiveDatabase()); 234 // HANDLE JMXREMOTE PASSWORD AND ACCESS FILE. 235 res.append(getJMXremoteFilesCommand()); 236 // END OF SCRIPT 237 return res.toString(); 238 } 239 240 /** 241 * Creates the operation system specific killing script for this machine. 242 * <p> 243 * pseudocode: - ssh 'login'@'machine' cmd /c 'environmentName'\\conf\\killall.bat 244 * <p> 245 * variables: 'login' = machine user name 'machine' = name of the machine 'environmentName' = the environmentName 246 * from configuration. 247 * 248 * @return Operation system specific part of the killscript. 249 */ 250 @Override 251 protected String osKillScript() { 252 StringBuilder res = new StringBuilder(); 253 res.append(ScriptConstants.SSH + Constants.SPACE); 254 res.append(machineUserLogin()); 255 res.append(Constants.SPACE + Constants.QUOTE_MARK + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE 256 + Constants.SPACE); 257 res.append(getLocalConfDirPath()); 258 res.append(Constants.SCRIPT_NAME_KILL_ALL); 259 res.append(scriptExtension); 260 res.append(Constants.SPACE + Constants.QUOTE_MARK + Constants.SPACE); 261 res.append(Constants.NEWLINE); 262 return res.toString(); 263 } 264 265 /** 266 * Creates the operation system specific starting script for this machine. 267 * <p> 268 * pseudocode: - ssh 'login'@'machine' cmd /c 'environmentName'\\conf\\startall.bat - sleep 5 - ssh 269 * 'login'@'machine' "more 'environmentName'\\start_APP.log 270 * <p> 271 * variables: 'login' = machine user name 'machine' = name of the machine 'environmentName' = the environmentName 272 * from configuration. 273 * 274 * @return Operation system specific part of the startscript. 275 */ 276 @Override 277 protected String osStartScript() { 278 StringBuilder res = new StringBuilder(); 279 // - ssh 'login'@'machine' cmd /c 'environmentName'\\conf\\startall.bat 280 res.append(ScriptConstants.SSH + Constants.SPACE); 281 res.append(machineUserLogin()); 282 res.append(Constants.SPACE + Constants.QUOTE_MARK + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE 283 + Constants.SPACE); 284 res.append(getLocalConfDirPath()); 285 res.append(Constants.SCRIPT_NAME_START_ALL); 286 res.append(scriptExtension); 287 res.append(Constants.SPACE + Constants.QUOTE_MARK + Constants.SPACE); 288 res.append(Constants.NEWLINE); 289 // - sleep 5 290 res.append(ScriptConstants.SLEEP_5); 291 res.append(Constants.NEWLINE); 292 // - ssh 'login'@'machine' "more 'environmentName'\\start_APP.log" 293 for (Application app : applications) { 294 res.append(ScriptConstants.SSH + Constants.SPACE); 295 res.append(machineUserLogin()); 296 res.append(Constants.SPACE + Constants.QUOTE_MARK + ScriptConstants.WINDOWS_COMMAND_TYPE + Constants.SPACE); 297 res.append(getEnvironmentName() + Constants.BACKSLASH + Constants.SCRIPT_NAME_LOCAL_START 298 + app.getIdentification() + Constants.EXTENSION_LOG_FILES); 299 res.append(Constants.QUOTE_MARK + Constants.SPACE); 300 res.append(Constants.NEWLINE); 301 } 302 303 return res.toString(); 304 } 305 306 @Override 307 protected String getInstallDirPath() { 308 return machineParameters.getInstallDirValue() + Constants.BACKSLASH + getEnvironmentName(); 309 } 310 311 @Override 312 protected String getConfDirPath() { 313 return getInstallDirPath() + Constants.CONF_DIR_WINDOWS; 314 } 315 316 @Override 317 protected String getLibDirPath() { 318 return getInstallDirPath() + Constants.LIB_DIR_WINDOWS; 319 } 320 321 /** 322 * Creates the local path to the conf dir. 323 * 324 * @return The path to the conf dir for ssh. 325 */ 326 protected String getLocalConfDirPath() { 327 return getEnvironmentName() + Constants.CONF_DIR_WINDOWS; 328 } 329 330 /** 331 * Creates the local path to the lib dir. 332 * 333 * @return The path to the lib dir for ssh. 334 */ 335 protected String getLocalLibDirPath() { 336 return getEnvironmentName() + Constants.LIB_DIR_WINDOWS; 337 } 338 339 /** 340 * Creates the local path to the installation directory. 341 * 342 * @return The path to the installation directory for ssh. 343 */ 344 protected String getLocalInstallDirPath() { 345 return getEnvironmentName() + Constants.BACKSLASH; 346 } 347 348 /** 349 * This function creates the script to kill all applications on this machine. The scripts calls all the kill script 350 * for each application. 351 * 352 * @param directory The directory for this machine (use global variable?). 353 * @throws IOFailure If an error occurred during the creation of the local killall script. 354 */ 355 @Override 356 protected void createOSLocalKillAllScript(File directory) throws IOFailure { 357 // create the kill all script file 358 File killAllScript = new File(directory, Constants.SCRIPT_NAME_KILL_ALL + scriptExtension); 359 try { 360 // Initialise script 361 PrintWriter killPrinter = new PrintWriter(killAllScript, getTargetEncoding()); 362 try { 363 killPrinter.println(ScriptConstants.ECHO_KILL_ALL_APPS + Constants.COLON + Constants.SPACE 364 + Constants.APOSTROPHE + hostname + Constants.APOSTROPHE); 365 killPrinter.println(ScriptConstants.CD + Constants.SPACE + Constants.QUOTE_MARK + getConfDirPath() 366 + Constants.QUOTE_MARK); 367 // insert path to kill script for all applications 368 for (Application app : applications) { 369 // make name of file 370 String appScript = Constants.SCRIPT_NAME_LOCAL_KILL + app.getIdentification() + scriptExtension; 371 killPrinter.print(ScriptConstants.OPERATING_SYSTEM_WINDOWS_RUN_BATCH_FILE); 372 killPrinter.print(Constants.QUOTE_MARK); 373 killPrinter.print(appScript); 374 killPrinter.print(Constants.QUOTE_MARK); 375 killPrinter.println(); 376 } 377 // Add 10 seconds timeout to allow the shutdown to complete before exiting the ssh connection 378 killPrinter.print(ScriptConstants.OPERATING_SYSTEM_WINDOWS_10_SECONDS_WAIT); 379 killPrinter.println(); 380 } finally { 381 // close script 382 killPrinter.close(); 383 } 384 } catch (IOException e) { 385 String msg = "Problems creating local kill all script. "; 386 log.trace(msg, e); 387 throw new IOFailure(msg, e); 388 } 389 } 390 391 /** 392 * This function creates the script to start all applications on this machine. The scripts calls all the start 393 * script for each application. 394 * 395 * @param directory The directory for this machine (use global variable?). 396 * @throws IOFailure If an error occurred during the creation of the local startall script. 397 */ 398 @Override 399 protected void createOSLocalStartAllScript(File directory) throws IOFailure { 400 // create the start all script file 401 File startAllScript = new File(directory, Constants.SCRIPT_NAME_START_ALL + scriptExtension); 402 try { 403 // Initialise script 404 PrintWriter startPrinter = new PrintWriter(startAllScript, getTargetEncoding()); 405 try { 406 startPrinter.println(ScriptConstants.ECHO_START_ALL_APPS + Constants.COLON + Constants.SPACE 407 + Constants.APOSTROPHE + hostname + Constants.APOSTROPHE); 408 startPrinter.println(ScriptConstants.CD + Constants.SPACE + Constants.QUOTE_MARK + getConfDirPath() 409 + Constants.QUOTE_MARK); 410 // insert path to kill script for all applications 411 for (Application app : applications) { 412 // make name of file 413 String appScript = Constants.SCRIPT_NAME_LOCAL_START + app.getIdentification() + scriptExtension; 414 startPrinter.print(ScriptConstants.OPERATING_SYSTEM_WINDOWS_RUN_BATCH_FILE); 415 startPrinter.print(Constants.QUOTE_MARK); 416 startPrinter.print(appScript); 417 startPrinter.print(Constants.QUOTE_MARK); 418 startPrinter.println(); 419 } 420 // Add 10 seconds timeout to allow the Starting to complete before exiting the ssh connection 421 startPrinter.print(ScriptConstants.OPERATING_SYSTEM_WINDOWS_10_SECONDS_WAIT); 422 startPrinter.println(); 423 } finally { 424 // close script 425 startPrinter.close(); 426 } 427 } catch (IOException e) { 428 String msg = "Problems during creation of the local start " + "all script."; 429 log.trace(msg, e); 430 throw new IOFailure(msg, e); 431 } 432 } 433 434 /** 435 * Creates the kill scripts for all the applications. Two script files are created: kill_app.bat and 436 * kill_ps_app.bat. 437 * <p> 438 * kill_ps_app.bat kills the process of the application. kill_app.bat runs kill_ps_app.bat if the application is 439 * running. run_app tells if the application is running. It is deleted during kill. 440 * <p> 441 * The kill_app.bat should have the following structure: 442 * <p> 443 * - ECHO Killing application : app - CD "path" - IF EXIST run_app GOTO KILL - GOTO NOKILL - - :KILL - cmdrun 444 * kill_ps_app.bat - DEL run_app - GOTO DONE - - :NOKILL - ECHO Cannot kill application. Already running. - - :DONE 445 * <p> 446 * where: app = application name. path = the path to the ./conf directory. cmdrun = the windows command to run other 447 * batch programs. 448 * <p> 449 * The kill_ps_app.bat is empty upon creation. When the application is started, the command to kill the process of 450 * he application is written to this file as the only content. It will look something like this: 451 * <p> 452 * - taskkill /F /PID id 453 * <p> 454 * where: id = the process identification number of the running application. 455 * <p> 456 * TODO kill the potential heritrix process, created by a harvester. Just like on Linux/Unix. If we in the future 457 * add the possibility of running heritrix on Windows. 458 * 459 * @param directory The directory for this machine (use global variable?). 460 * @throws IOFailure If an error occurred during the creation of the application kill script file. 461 */ 462 @Override 463 protected void createApplicationKillScripts(File directory) throws IOFailure { 464 // go through all applications and create their kill script 465 for (Application app : applications) { 466 String id = app.getIdentification(); 467 String killPsName = Constants.SCRIPT_KILL_PS + id + scriptExtension; 468 File appKillScript = new File(directory, Constants.SCRIPT_NAME_LOCAL_KILL + id + scriptExtension); 469 File appKillPsScript = new File(directory, killPsName); 470 try { 471 // make print writer for writing to file 472 PrintWriter appPrint = new PrintWriter(appKillScript, getTargetEncoding()); 473 try { 474 // initiate variables 475 String tmpRunApp = Constants.FILE_TEMPORARY_RUN_WINDOWS_NAME + id; 476 // get the content for the kill script of 477 // this application 478 // #echo kill windows application 479 appPrint.println(ScriptConstants.ECHO_KILL_WINDOWS_APPLICATION + Constants.COLON + Constants.SPACE 480 + id); 481 // cd "path" 482 appPrint.println(ScriptConstants.CD + Constants.SPACE + Constants.QUOTE_MARK 483 + app.installPathWindows() + Constants.CONF_DIR_WINDOWS + Constants.QUOTE_MARK); 484 // if exist run_app.txt GOTO KILL 485 appPrint.println(ScriptConstants.IF + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE 486 + tmpRunApp + Constants.SPACE + ScriptConstants.GOTO + Constants.SPACE 487 + ScriptConstants.LABEL_KILL); 488 // GOTO NOKILL 489 appPrint.println(ScriptConstants.GOTO + Constants.SPACE + ScriptConstants.LABEL_NOKILL); 490 // 491 appPrint.println(); 492 // :KILL 493 appPrint.println(Constants.COLON + ScriptConstants.LABEL_KILL); 494 // cmdrun kill_ps_app.bat 495 appPrint.println(ScriptConstants.OPERATING_SYSTEM_WINDOWS_RUN_BATCH_FILE + Constants.QUOTE_MARK 496 + killPsName + Constants.QUOTE_MARK); 497 // del run_app.txt 498 appPrint.println(ScriptConstants.DEL + Constants.SPACE + tmpRunApp); 499 // GOTO DONE 500 appPrint.println(ScriptConstants.GOTO + Constants.SPACE + ScriptConstants.LABEL_DONE); 501 // 502 appPrint.println(); 503 // :NOKILL 504 appPrint.println(Constants.COLON + ScriptConstants.LABEL_NOKILL); 505 // echo Cannot kill application. Already running. 506 appPrint.println(ScriptConstants.ECHO_CANNOT_KILL_APP); 507 // 508 appPrint.println(); 509 // :DONE 510 appPrint.println(Constants.COLON + ScriptConstants.LABEL_DONE); 511 } finally { 512 // close file 513 appPrint.close(); 514 } 515 // Printer for making the kill process file. 516 PrintWriter appPsPrint = new PrintWriter(appKillPsScript, getTargetEncoding()); 517 try { 518 // write dummy line in kill script. 519 appPsPrint.println("ECHO Not started!"); 520 } finally { 521 // close file 522 appPsPrint.close(); 523 } 524 } catch (IOException e) { 525 String msg = "Cannot create the kill script for " + "application: " + app.getIdentification() 526 + ", at machine: '" + hostname + "'"; 527 log.trace(msg, e); 528 throw new IOFailure(msg, e); 529 } 530 } 531 } 532 533 /** 534 * Creates the start scripts for all the applications. 535 * <p> 536 * It creates the batch and the VBscript for starting the application, which are called start_app.bat and 537 * start_app.vbs respectively. These files are created in each of their own function. 538 * 539 * @param directory The directory for this machine (use global variable?). 540 * @see #windowsStartBatScript(Application, File) 541 * @see #windowsStartVbsScript(Application, File) 542 */ 543 @Override 544 protected void createApplicationStartScripts(File directory) { 545 // go through all applications and create their start script 546 for (Application app : applications) { 547 windowsStartBatScript(app, directory); 548 windowsStartVbsScript(app, directory); 549 } 550 } 551 552 @Override 553 protected String osGetClassPath(Application app) { 554 StringBuilder res = new StringBuilder(); 555 // get all the classpaths (change from '\' to '\\') 556 for (Element cp : app.getMachineParameters().getClassPaths()) { 557 // insert the path to the install directory 558 res.append(ScriptConstants.doubleBackslashes(getInstallDirPath())); 559 res.append(Constants.BACKSLASH + Constants.BACKSLASH); 560 // Then insert the class path. 561 res.append(ScriptConstants.replaceWindowsDirSeparators(cp.getText())); 562 res.append(Constants.SEMICOLON); 563 } 564 return res.toString(); 565 } 566 567 /** 568 * Creates the batch script for starting the application. It checks if the application is running and starts the 569 * application if it is not the case. The application is started by calling the start_app.vbs. 570 * <p> 571 * The script should be the following: 572 * <p> 573 * - echo Starting windows application : app - cd "path" - if exist ".\conf\run_app.txt" goto NOSTART - goto START - 574 * - :START - cscript .\conf\start_app.vbs - goto DONE - - :NOSTART - echo Application already running. - - :DONE 575 * <p> 576 * where: app = the name of the application. path = the path to the installation directory. 577 * 578 * @param app The application to start. 579 * @param directory The directory where the script should be placed. 580 * @throws IOFailure If an error occurred during the creation of the windows start bat script. 581 */ 582 protected void windowsStartBatScript(Application app, File directory) throws IOFailure { 583 File appStartScript = new File(directory, Constants.SCRIPT_NAME_LOCAL_START + app.getIdentification() 584 + scriptExtension); 585 try { 586 // make print writer for writing to file 587 PrintWriter appPrint = new PrintWriter(appStartScript, getTargetEncoding()); 588 try { 589 // initiate variables 590 String id = app.getIdentification(); 591 String tmpRunApp = Constants.FILE_TEMPORARY_RUN_WINDOWS_NAME + id; 592 593 // cd "path" 594 appPrint.println(ScriptConstants.CD + Constants.SPACE + Constants.QUOTE_MARK + app.installPathWindows() 595 + Constants.QUOTE_MARK); 596 // if exist .\conf\run_app.txt GOTO NOSTART 597 appPrint.println(ScriptConstants.IF + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE 598 + Constants.DOT + Constants.CONF_DIR_WINDOWS + tmpRunApp + Constants.SPACE 599 + ScriptConstants.GOTO + Constants.SPACE + ScriptConstants.LABEL_NOSTART); 600 // GOTO START 601 appPrint.println(ScriptConstants.GOTO + Constants.SPACE + ScriptConstants.LABEL_START); 602 // 603 appPrint.println(); 604 // :START 605 appPrint.println(Constants.COLON + ScriptConstants.LABEL_START); 606 // cscript .\conf\start_app.vbs 607 appPrint.println(ScriptConstants.CSCRIPT + Constants.SPACE + Constants.DOT + Constants.CONF_DIR_WINDOWS 608 + Constants.SCRIPT_NAME_LOCAL_START + id + Constants.EXTENSION_VBS_FILES); 609 // GOTO DONE 610 appPrint.println(ScriptConstants.GOTO + Constants.SPACE + ScriptConstants.LABEL_DONE); 611 // 612 appPrint.println(); 613 // :NOSTART 614 appPrint.println(Constants.COLON + ScriptConstants.LABEL_NOSTART); 615 // echo Cannot start. Application already running. 616 appPrint.println(ScriptConstants.ECHO_CANNOT_START_APP); 617 // 618 appPrint.println(); 619 // :DONE 620 appPrint.println(Constants.COLON + ScriptConstants.LABEL_DONE); 621 } finally { 622 // close file 623 appPrint.close(); 624 } 625 } catch (IOException e) { 626 String msg = "Cannot create the start script for application: " + app.getIdentification() 627 + ", at machine: '" + hostname + "'"; 628 log.trace(msg, e); 629 throw new IOFailure(msg, e); 630 } 631 } 632 633 protected static final class windowsStartVbsScriptTpl { 634 protected static final String[] mainScript = { 635 "Set WshShell= CreateObject(\"WScript.Shell\")", 636 "javahome = WshShell.ExpandEnvironmentStrings(\"%JAVA_HOME%\")", 637 "WScript.Echo \"JAVA_HOME=\" & javahome", 638 "If javahome = \"%JAVA_HOME%\" Then", 639 " java = \"java\"", 640 "Else", 641 " java = javahome & \"\\bin\\java\"", 642 "End If", 643 "Set oExec = WshShell.exec(\"\"\"java\"\"\" & \" ${machineparameters} -classpath \"\"${classpath}\"\"" 644 + " -Ddk.netarkivet.settings.file=\"\"${confdirpath}settings_${id}.xml\"\"" 645 + "${slf4jlogger}" + "${securityManagement}" + " ${appname}" + "\")", 646 "Set fso= CreateObject(\"Scripting.FileSystemObject\")", 647 "Set f=fso.OpenTextFile(\".\\conf\\${killpsname}\",2,True)", 648 "f.WriteLine \"taskkill /F /PID \" & oExec.ProcessID", 649 "f.close", 650 "Set tf=fso.OpenTextFile(\".\\conf\\${tmprunpsname}\",8,True)", 651 "tf.WriteLine \"running process: \" & oExec.ProcessID", 652 "tf.close", 653 "'Create a new start-log for the application", 654 "CreateObject(\"Scripting.FileSystemObject\").OpenTextFile(\"${startlogname}\", 2, True).close", 655 "Do While oExec.Status = 0 Or oExec.StdOut.AtEndOfStream <> True Or oExec.StdErr.AtEndOfStream <> True", 656 " WScript.Sleep 1000", 657 " Do While oExec.StdOut.AtEndOfStream <> True", 658 " Set outFile = CreateObject(\"Scripting.FileSystemObject\").OpenTextFile(\"${startlogname}\", 8, True)", 659 " outFile.WriteLine oExec.StdOut.ReadLine", 660 " outFile.close", 661 " Loop", 662 " Do While oExec.StdErr.AtEndOfStream <> True", 663 " Set outFile = CreateObject(\"Scripting.FileSystemObject\").OpenTextFile(\"${startlogname}\", 8, True)", 664 " outFile.WriteLine oExec.StdErr.ReadLine", " outFile.close", " Loop", "Loop"}; 665 protected static final String slf4jLogger = " -Dlogback.configurationFile=\"\"${confdirpath}logback_${id}.xml\"\""; 666 protected static final String securityManagement = " -Djava.security.manager -Djava.security.policy=\"\"${confdirpath}security.policy\"\""; 667 } 668 669 /** 670 * This function creates the VBscript to start the application. It calls a command for executing the java 671 * application, then it writes the way to kill the process in the kill_ps_app.bat and finally it creates the 672 * run-file. 673 * <p> 674 * It should have the following content: - set WshShell = CreateObject("WScript.Shell") - set oExec = WshShell.exec( 675 * JAVA ) - set fso = CreateObject("Scripting.FileSystemObject") - set f = 676 * fso.OpenTextFile(".\conf\kill_ps_app.bat", 2, True) - f.WriteLine "taskkill /F /PID " & oExec.ProcessID - f.close 677 * - 'Create a new start-log for the application - CreateObject("Scripting.FileSystemObject").OpenTextFile(" 678 * start_APP.log", 2, True).close - Do While oExec.Status = 0 - WScript.Sleep 1000 - Do While 679 * oExec.StdOut.AtEndOfStream <> True - Set outFile = CreateObject("Scripting.FileSystemObject") 680 * .OpenTextFile("start_APP.log", 8, True) - outFile.WriteLine oExec.StdOut.ReadLine - outFile.close - Loop - Do 681 * While oExec.StdErr.AtEndOfStream <> True - Set outFile = CreateObject("Scripting.FileSystemObject") 682 * .OpenTextFile("start_APP.log", 8, True) - outFile.WriteLine oExec.StdErr.ReadLine - outFile.close - Loop - Loop 683 * <p> 684 * where: JAVA = the command for starting the java application (very long). app = the name of the application. 685 * 686 * @param app The application to start. 687 * @param directory The directory where the script should be placed. 688 * @throws IOFailure If an error occurred during the creation of the windows vb script. 689 */ 690 protected void windowsStartVbsScript(Application app, File directory) throws IOFailure { 691 File appStartSupportScript = new File(directory, Constants.SCRIPT_NAME_LOCAL_START + app.getIdentification() 692 + Constants.EXTENSION_VBS_FILES); 693 try { 694 // make print writer for writing to file 695 PrintWriter vbsPrint = new PrintWriter(appStartSupportScript, getTargetEncoding()); 696 try { 697 // initiate variables 698 String id = app.getIdentification(); 699 String killPsName = Constants.SCRIPT_KILL_PS + id + scriptExtension; 700 String tmpRunPsName = Constants.FILE_TEMPORARY_RUN_WINDOWS_NAME + id; 701 String startLogName = Constants.SCRIPT_NAME_LOCAL_START + id + Constants.EXTENSION_LOG_FILES; 702 703 Map<String, String> env = new HashMap<String, String>(); 704 env.put("machineparameters", app.getMachineParameters().writeJavaOptions()); 705 env.put("classpath", osGetClassPath(app)); 706 env.put("confdirpath", ScriptConstants.doubleBackslashes(getConfDirPath())); 707 env.put("id", id); 708 env.put("appname", app.getTotalName()); 709 env.put("killpsname", killPsName); 710 env.put("tmprunpsname", tmpRunPsName); 711 env.put("startlogname", startLogName); 712 if (inheritedSlf4jConfigFile != null) { 713 env.put("slf4jlogger", Template.untemplate(windowsStartVbsScriptTpl.slf4jLogger, env, true)); 714 } else { 715 env.put("slf4jlogger", ""); 716 } 717 if (app.getTotalName().contains(ScriptConstants.BITARCHIVE_APPLICATION_NAME)) { 718 env.put("securityManagement", 719 Template.untemplate(windowsStartVbsScriptTpl.securityManagement, env, true)); 720 } else { 721 env.put("securityManagement", ""); 722 } 723 String str = Template.untemplate(windowsStartVbsScriptTpl.mainScript, env, true, "\r\n"); 724 vbsPrint.print(str); 725 } finally { 726 // close file 727 vbsPrint.close(); 728 } 729 } catch (IOException e) { 730 String msg = "Cannot create the start script for application: " + app.getIdentification() 731 + ", at machine: '" + hostname + "'"; 732 log.trace(msg, e); 733 throw new IOFailure(msg, e); 734 } 735 } 736 737 /** 738 * THIS HAS NOT BEEN IMPLEMENTED FOR WINDOWS YET - ONLY LINUX! 739 * <p> 740 * Checks if a specific directory for the database is given in the settings, and thus if the database should be 741 * installed on this machine. 742 * <p> 743 * If no specific database is given (databaseFileName = null) then use the standard database extracted from 744 * NetarchiveSuite.zip. Else send the given new database to the standard database location. 745 * <p> 746 * Extract the database in the standard database location to the specified database directory. 747 * 748 * @return The script for installing the database (if needed). 749 */ 750 @Override 751 protected String osInstallDatabase() { 752 String databaseDir = machineParameters.getHarvestDatabaseDirValue(); 753 // Do not install if no proper database directory. 754 if (databaseDir == null || databaseDir.isEmpty()) { 755 return Constants.EMPTY; 756 } 757 758 StringBuilder res = new StringBuilder(ScriptConstants.ECHO_WINDOWS_DATABASE); 759 res.append(Constants.NEWLINE); 760 761 return res.toString(); 762 } 763 764 /** 765 * THIS HAS NOT BEEN IMPLEMENTED FOR WINDOWS YET - ONLY LINUX! 766 * <p> 767 * Checks if a specific directory for the archive database is given in the settings, and thus if the archive 768 * database should be installed on this machine. 769 * <p> 770 * If not specific database is given (archiveDatabaseFileName = null) then use the default in the 771 * NetarchiveSuite.zip package. Else send the new archive database to the standard database location, and extract it 772 * to the given location. 773 * 774 * @return The script for installing the archive database (if needed). 775 */ 776 @Override 777 protected String osInstallArchiveDatabase() { 778 String bpDatabaseDir = machineParameters.getArchiveDatabaseDirValue(); 779 780 // Do not install if no proper archive database directory. 781 if (bpDatabaseDir == null || bpDatabaseDir.isEmpty()) { 782 return Constants.EMPTY; 783 } 784 785 StringBuilder res = new StringBuilder(ScriptConstants.ECHO_WINDOWS_DATABASE); 786 res.append(Constants.NEWLINE); 787 788 return res.toString(); 789 } 790 791 @Override 792 protected String osInstallExternalJarFiles() { 793 if (jarFolder == null) { 794 return Constants.EMPTY; 795 } 796 797 StringBuilder res = new StringBuilder(); 798 799 // Comment about copying files. 800 res.append(ScriptConstants.ECHO_INSTALLING_EXTERNAL_JAR_FILES); 801 res.append(Constants.NEWLINE); 802 // if [ -d folder ]; then ssh machine "md installdir/external"; 803 // scp folder/* machine:installdir/external; fi; 804 res.append(ScriptConstants.LINUX_IF_DIR_EXIST + Constants.SPACE); 805 res.append(jarFolder.getPath()); 806 res.append(Constants.SPACE + ScriptConstants.LINUX_THEN + Constants.SPACE); 807 res.append(ScriptConstants.SSH + Constants.SPACE); 808 res.append(machineUserLogin()); 809 res.append(Constants.SPACE + ScriptConstants.MD + Constants.SPACE + Constants.QUOTE_MARK); 810 res.append(ScriptConstants.doubleBackslashes(getInstallDirPath())); 811 res.append(Constants.BACKSLASH + Constants.BACKSLASH + Constants.EXTERNAL_JAR_DIRECTORY + Constants.QUOTE_MARK 812 + Constants.SEMICOLON); 813 res.append(Constants.SPACE + ScriptConstants.SCP + Constants.SPACE + ScriptConstants.DASH_R + Constants.SPACE); 814 res.append(jarFolder.getPath()); 815 res.append(Constants.SLASH + Constants.STAR); 816 res.append(Constants.SPACE); 817 res.append(machineUserLogin()); 818 res.append(Constants.COLON + Constants.QUOTE_MARK); 819 res.append(ScriptConstants.doubleBackslashes(getInstallDirPath())); 820 res.append(Constants.BACKSLASH + Constants.BACKSLASH + Constants.EXTERNAL_JAR_DIRECTORY + Constants.QUOTE_MARK); 821 res.append(Constants.SEMICOLON + Constants.SPACE + ScriptConstants.FI + Constants.SEMICOLON); 822 res.append(Constants.NEWLINE); 823 824 return res.toString(); 825 } 826 827 /** 828 * Creates the specified directories in the deploy config file. 829 * 830 * @return The script for creating the directories. 831 */ 832 @Override 833 protected String osInstallScriptCreateDir() { 834 StringBuilder res = new StringBuilder(); 835 836 res.append(ScriptConstants.ECHO_CREATING_DIRECTORIES); 837 res.append(Constants.NEWLINE); 838 839 // send script to machine 840 res.append(ScriptConstants.SCP + Constants.SPACE); 841 res.append(getMakeDirectoryName()); 842 res.append(Constants.SPACE); 843 res.append(machineUserLogin()); 844 res.append(Constants.COLON); 845 res.append(Constants.NEWLINE); 846 847 // run script 848 res.append(ScriptConstants.SSH + Constants.SPACE + Constants.SPACE); 849 res.append(machineUserLogin()); 850 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE); 851 res.append(getMakeDirectoryName()); 852 res.append(Constants.NEWLINE); 853 854 // delete script 855 res.append(ScriptConstants.SSH + Constants.SPACE + Constants.SPACE); 856 res.append(machineUserLogin()); 857 res.append(Constants.SPACE + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE + ScriptConstants.DEL 858 + Constants.SPACE); 859 res.append(getMakeDirectoryName()); 860 res.append(Constants.NEWLINE); 861 862 return res.toString(); 863 } 864 865 @Override 866 protected String scriptCreateDir(String dir, boolean clean) { 867 StringBuilder res = new StringBuilder(); 868 869 if (clean) { 870 res.append(ScriptConstants.IF + Constants.SPACE + ScriptConstants.EXIST + Constants.SPACE); 871 res.append(dir); 872 res.append(Constants.SPACE + ScriptConstants.RD + Constants.SPACE); 873 res.append(dir); 874 res.append(Constants.NEWLINE); 875 } 876 res.append(ScriptConstants.IF + Constants.SPACE + ScriptConstants.NOT + Constants.SPACE + ScriptConstants.EXIST 877 + Constants.SPACE); 878 res.append(dir); 879 res.append(Constants.SPACE + ScriptConstants.MD + Constants.SPACE); 880 res.append(dir); 881 882 res.append(Constants.NEWLINE); 883 884 return res.toString(); 885 } 886 887 /** 888 * Function for creating the directories along the path until the end directory. Does not create the end directory. 889 * 890 * @param dir The path to the directory. 891 * @return The script for creating the directory. 892 */ 893 protected String createPathToDir(String dir) { 894 StringBuilder res = new StringBuilder(); 895 896 String[] pathDirs = dir.split(Constants.REGEX_BACKSLASH_CHARACTER); 897 StringBuilder path = new StringBuilder(); 898 899 // only make directories along path to last directory, 900 // don't create end directory. 901 for (int i = 0; i < pathDirs.length - 1; i++) { 902 // don't make directory of empty path. 903 if (!pathDirs[i].isEmpty()) { 904 path.append(pathDirs[i]); 905 if (!path.substring(path.length() - 1).endsWith(Constants.COLON)) { 906 res.append(scriptCreateDir(path.toString(), false)); 907 } 908 } 909 path.append(Constants.BACKSLASH); 910 } 911 912 return res.toString(); 913 } 914 915 @Override 916 protected String getAppDirectories() { 917 StringBuilder res = new StringBuilder(); 918 String[] dirs; 919 920 for (Application app : applications) { 921 // get archive.fileDir directories. 922 dirs = app.getSettingsValues(Constants.SETTINGS_BITARCHIVE_BASEFILEDIR_LEAF); 923 if (dirs != null && dirs.length > 0) { 924 for (String dir : dirs) { 925 res.append(createPathToDir(dir)); 926 res.append(scriptCreateDir(dir, false)); 927 for (String subdir : Constants.BASEFILEDIR_SUBDIRECTORIES) { 928 res.append(scriptCreateDir(dir + Constants.BACKSLASH + subdir, false)); 929 } 930 } 931 } 932 933 // get harvester.harvesting.serverDir directories. 934 dirs = app.getSettingsValues(Constants.SETTINGS_HARVEST_SERVERDIR_LEAF); 935 if (dirs != null && dirs.length > 0) { 936 for (String dir : dirs) { 937 res.append(createPathToDir(dir)); 938 res.append(scriptCreateDir(dir, false)); 939 } 940 } 941 942 // get the viewerproxy.baseDir directories. 943 dirs = app.getSettingsValues(Constants.SETTINGS_VIEWERPROXY_BASEDIR_LEAF); 944 if (dirs != null && dirs.length > 0) { 945 for (String dir : dirs) { 946 res.append(createPathToDir(dir)); 947 res.append(scriptCreateDir(dir, false)); 948 } 949 } 950 951 // get the common.tempDir directories. But only those, 952 // which are not the same as the machine common.tempDir. 953 dirs = app.getSettingsValues(Constants.SETTINGS_TEMPDIR_LEAF); 954 if (dirs != null && dirs.length > 0) { 955 String machineDir = settings.getLeafValue(Constants.SETTINGS_TEMPDIR_LEAF); 956 for (String dir : dirs) { 957 // Don't make machine temp dir twice. 958 if (!dir.equals(machineDir)) { 959 res.append(createPathToDir(dir)); 960 res.append(scriptCreateDir(dir, resetTempDir)); 961 } 962 } 963 } 964 } 965 966 return res.toString(); 967 } 968 969 /** 970 * Creates the name for the make dir script. 971 * 972 * @return The name of the script for creating the directories. 973 */ 974 protected String getMakeDirectoryName() { 975 return Constants.WINDOWS_DIR_CREATE_PREFIX + hostname + scriptExtension; 976 } 977 978 /** 979 * Function to create the script which installs the new directories. This is only used for windows machines! 980 * 981 * @param directory The directory to put the file. 982 * @throws IOFailure If an error occurred during the creation of the install-dir script. 983 */ 984 @Override 985 protected void createInstallDirScript(File directory) throws IOFailure { 986 File dirScript = new File(directory, getMakeDirectoryName()); 987 try { 988 // make print writer for writing to file 989 PrintWriter dirPrint = new PrintWriter(dirScript, getTargetEncoding()); 990 try { 991 // go to correct directory 992 dirPrint.print(ScriptConstants.CD + Constants.SPACE); 993 dirPrint.print(getInstallDirPath()); 994 dirPrint.print(Constants.NEWLINE); 995 996 // go through all directories. 997 String dir; 998 999 // get archive.bitpresevation.baseDir directory. 1000 dir = settings.getLeafValue(Constants.SETTINGS_ARCHIVE_BP_BASEDIR_LEAF); 1001 if (dir != null && !dir.isEmpty() && !dir.equalsIgnoreCase(Constants.DOT)) { 1002 dirPrint.print(createPathToDir(dir)); 1003 dirPrint.print(scriptCreateDir(dir, false)); 1004 } 1005 1006 // get archive.arcrepository.baseDir directory. 1007 dir = settings.getLeafValue(Constants.SETTINGS_ARCHIVE_ARC_BASEDIR_LEAF); 1008 if (dir != null && !dir.isEmpty() && !dir.equalsIgnoreCase(Constants.DOT)) { 1009 dirPrint.print(createPathToDir(dir)); 1010 dirPrint.print(scriptCreateDir(dir, false)); 1011 } 1012 1013 dirPrint.print(getAppDirectories()); 1014 1015 // get tempDir directory. 1016 dir = settings.getLeafValue(Constants.SETTINGS_TEMPDIR_LEAF); 1017 if (dir != null && !dir.isEmpty() && !dir.equalsIgnoreCase(Constants.DOT)) { 1018 dirPrint.print(createPathToDir(dir)); 1019 dirPrint.print(scriptCreateDir(dir, resetTempDir)); 1020 } 1021 } finally { 1022 // close file 1023 dirPrint.close(); 1024 } 1025 } catch (IOException e) { 1026 String msg = "Problems creating install directory script. "; 1027 log.trace(msg, e); 1028 throw new IOFailure(msg, e); 1029 } 1030 } 1031 1032 @Override 1033 protected String changeFileDirPathForSecurity(String path) { 1034 path += Constants.BACKSLASH + Constants.SECURITY_FILE_DIR_TAG + Constants.BACKSLASH; 1035 return path.replace(Constants.BACKSLASH, ScriptConstants.SECURITY_DIR_SEPARATOR); 1036 } 1037 1038 /** 1039 * This method does the following: 1040 * <p> 1041 * Retrieves the path to the jmxremote.access and jmxremote.password files. 1042 * <p> 1043 * Moves these files, if they are different from standard. This has to be a force move (command 'move /Y'). 1044 * <p> 1045 * Makes the jmxremote.access and jmxremote.password files readonly. 1046 * 1047 * @return The commands for handling the jmxremote files. 1048 */ 1049 @Override 1050 protected String getJMXremoteFilesCommand() { 1051 String accessFilePath; 1052 String passwordFilePath; 1053 String[] options; 1054 1055 // retrieve the access file path. 1056 options = settings.getLeafValues(Constants.SETTINGS_COMMON_JMX_ACCESSFILE); 1057 1058 // extract the path, if any. Else set default. 1059 if (options.length == 0) { 1060 accessFilePath = Constants.JMX_ACCESS_FILE_PATH_DEFAULT; 1061 } else { 1062 accessFilePath = options[0]; 1063 // warn if more than one access file is defined. 1064 if (options.length > 1) { 1065 log.debug(Constants.MSG_WARN_TOO_MANY_JMXREMOTE_FILE_PATHS); 1066 } 1067 } 1068 1069 // retrieve the password file path. 1070 options = settings.getLeafValues(Constants.SETTINGS_COMMON_JMX_PASSWORDFILE); 1071 1072 // extract the path, if any. Else set default. 1073 if (options.length == 0) { 1074 passwordFilePath = Constants.JMX_PASSWORD_FILE_PATH_DEFAULT; 1075 } else { 1076 passwordFilePath = options[0]; 1077 // warn if more than one access file is defined. 1078 if (options.length > 1) { 1079 log.debug(Constants.MSG_WARN_TOO_MANY_JMXREMOTE_FILE_PATHS); 1080 } 1081 } 1082 1083 // change the path to windows syntax. 1084 accessFilePath = ScriptConstants.replaceWindowsDirSeparators(accessFilePath); 1085 passwordFilePath = ScriptConstants.replaceWindowsDirSeparators(passwordFilePath); 1086 1087 // initialise the resulting command string. 1088 StringBuilder res = new StringBuilder(); 1089 1090 // - echo make password files readonly 1091 res.append(ScriptConstants.ECHO_MAKE_PASSWORD_FILES); 1092 res.append(Constants.NEWLINE); 1093 1094 // IF NOT DEFAULT PATHS, THEN MAKE SCRIPT TO MOVE THE FILES. 1095 if (!accessFilePath.equals(ScriptConstants.replaceWindowsDirSeparators(Constants.JMX_ACCESS_FILE_PATH_DEFAULT))) { 1096 // ssh dev@kb-test-adm-001.kb.dk "mv 1097 // installpath/conf/jmxremote.access installpath/accessFilePath" 1098 res.append(ScriptConstants.SSH + Constants.SPACE); 1099 res.append(machineUserLogin()); 1100 res.append(Constants.SPACE + Constants.QUOTE_MARK); 1101 res.append(ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE); 1102 res.append(ScriptConstants.WINDOWS_FORCE_MOVE); 1103 res.append(Constants.SPACE); 1104 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1105 res.append(ScriptConstants.replaceWindowsDirSeparators(Constants.JMX_ACCESS_FILE_PATH_DEFAULT)); 1106 res.append(Constants.SPACE); 1107 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1108 res.append(accessFilePath); 1109 res.append(Constants.QUOTE_MARK); 1110 res.append(Constants.NEWLINE); 1111 } 1112 1113 if (!passwordFilePath.equals(ScriptConstants 1114 .replaceWindowsDirSeparators(Constants.JMX_PASSWORD_FILE_PATH_DEFAULT))) { 1115 // ssh dev@kb-test-adm-001.kb.dk "mv 1116 // installpath/conf/jmxremote.access installpath/accessFilePath" 1117 res.append(ScriptConstants.SSH + Constants.SPACE); 1118 res.append(machineUserLogin()); 1119 res.append(Constants.SPACE + Constants.QUOTE_MARK); 1120 res.append(ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE); 1121 res.append(ScriptConstants.WINDOWS_FORCE_MOVE); 1122 res.append(Constants.SPACE); 1123 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1124 res.append(ScriptConstants.replaceWindowsDirSeparators(Constants.JMX_PASSWORD_FILE_PATH_DEFAULT)); 1125 res.append(Constants.SPACE); 1126 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1127 res.append(passwordFilePath); 1128 res.append(Constants.QUOTE_MARK); 1129 res.append(Constants.NEWLINE); 1130 } 1131 1132 // - echo Y | ssh 'login'@'machine' cmd /c cacls 1133 // 'environmentName'\\conf\\jmxremote.password /P BITARKIV\\'login':R 1134 res.append(ScriptConstants.ECHO_Y + Constants.SPACE + Constants.SEPARATOR + Constants.SPACE 1135 + ScriptConstants.SSH + Constants.SPACE); 1136 res.append(machineUserLogin()); 1137 res.append(Constants.SPACE + Constants.QUOTE_MARK + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE 1138 + ScriptConstants.CACLS + Constants.SPACE); 1139 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1140 res.append(passwordFilePath); 1141 res.append(Constants.SPACE + ScriptConstants.SLASH_P + Constants.SPACE 1142 + ScriptConstants.BITARKIV_BACKSLASH_BACKSLASH); 1143 res.append(machineParameters.getMachineUserName().getText().trim()); 1144 res.append(ScriptConstants.COLON_R + Constants.QUOTE_MARK); 1145 res.append(Constants.NEWLINE); 1146 1147 // - echo Y | ssh 'login'@'machine' cmd /c cacls 1148 // 'environmentName'\\conf\\jmxremote.access /P BITARKIV\\'login':R 1149 res.append(ScriptConstants.ECHO_Y + Constants.SPACE + Constants.SEPARATOR + Constants.SPACE 1150 + ScriptConstants.SSH + Constants.SPACE); 1151 res.append(machineUserLogin()); 1152 res.append(Constants.SPACE + Constants.QUOTE_MARK + ScriptConstants.WINDOWS_COMMAND_RUN + Constants.SPACE 1153 + ScriptConstants.CACLS + Constants.SPACE); 1154 res.append(ScriptConstants.doubleBackslashes(getLocalInstallDirPath())); 1155 res.append(accessFilePath); 1156 res.append(Constants.SPACE + ScriptConstants.SLASH_P + Constants.SPACE 1157 + ScriptConstants.BITARKIV_BACKSLASH_BACKSLASH); 1158 res.append(machineParameters.getMachineUserName().getText().trim()); 1159 res.append(ScriptConstants.COLON_R + Constants.QUOTE_MARK); 1160 res.append(Constants.NEWLINE); 1161 1162 return res.toString(); 1163 } 1164 1165 /** 1166 * Creates scripts for restarting all the applications on a machine. This script should start by killing all the 1167 * existing processes, and then starting them again. 1168 * <p> 1169 * First the killall scripts is called, then wait for 5 seconds for the applications to be fully terminated, and 1170 * finally call the startall script. 1171 * <p> 1172 * The createWaitScript is called through this script to create the wait script which is used by the restart script. 1173 * 1174 * @param dir The directory where the script file will be placed. 1175 * @throws IOFailure If the restart script cannot be created, or if the wait script cannot be created. 1176 */ 1177 @Override 1178 protected void createRestartScript(File dir) throws IOFailure { 1179 // Start by creating the wait script. 1180 createWaitScript(dir); 1181 1182 try { 1183 // initialise the script file. 1184 File restartScript = new File(dir, Constants.SCRIPT_NAME_RESTART + scriptExtension); 1185 1186 // make print writer for writing to file 1187 PrintWriter restartPrint = new PrintWriter(restartScript, getTargetEncoding()); 1188 try { 1189 restartPrint.println(ScriptConstants.CD + Constants.SPACE + Constants.QUOTE_MARK + getConfDirPath() 1190 + Constants.QUOTE_MARK); 1191 1192 // call killall script. 1193 restartPrint.print(ScriptConstants.WINDOWS_COMMAND_RUN); 1194 restartPrint.print(Constants.SPACE); 1195 restartPrint.print(Constants.SCRIPT_NAME_KILL_ALL + scriptExtension); 1196 restartPrint.print(Constants.NEWLINE); 1197 1198 // call wait script. 1199 restartPrint.print(ScriptConstants.CSCRIPT); 1200 restartPrint.print(Constants.SPACE); 1201 restartPrint.print(Constants.SCRIPT_NAME_WAIT + Constants.EXTENSION_VBS_FILES); 1202 restartPrint.print(Constants.NEWLINE); 1203 1204 // call startall script. 1205 restartPrint.print(ScriptConstants.WINDOWS_COMMAND_RUN); 1206 restartPrint.print(Constants.SPACE); 1207 restartPrint.print(Constants.SCRIPT_NAME_START_ALL + scriptExtension); 1208 restartPrint.print(Constants.NEWLINE); 1209 } finally { 1210 // close file 1211 restartPrint.close(); 1212 } 1213 } catch (IOException e) { 1214 // Log the error and throw an IOFailure. 1215 log.trace(Constants.MSG_ERROR_RESTART_FILE, e); 1216 throw new IOFailure(Constants.MSG_ERROR_RESTART_FILE, e); 1217 } 1218 } 1219 1220 /** 1221 * Creates the script for waiting during restart. 1222 * 1223 * @param dir The directory where the script should be placed. 1224 * @throws IOFailure If the method fails in creating the wait script. 1225 */ 1226 protected void createWaitScript(File dir) throws IOFailure { 1227 try { 1228 // initialise the script file. 1229 File waitScript = new File(dir, Constants.SCRIPT_NAME_WAIT + Constants.EXTENSION_VBS_FILES); 1230 1231 // make print writer for writing to file 1232 PrintWriter waitPrint = new PrintWriter(waitScript, getTargetEncoding()); 1233 try { 1234 // Create the wait script. 1235 waitPrint.print(ScriptConstants.VB_WRITE_WAIT + Constants.SPACE 1236 + (Constants.WAIT_TIME_DURING_RESTART * Constants.TIME_SECOND_IN_MILLISECONDS)); 1237 waitPrint.print(Constants.NEWLINE); 1238 } finally { 1239 // close file 1240 waitPrint.close(); 1241 } 1242 } catch (IOException e) { 1243 // log error and throw a IOFailure. 1244 log.trace(Constants.MSG_ERROR_WAIT_FILE, e); 1245 throw new IOFailure(Constants.MSG_ERROR_WAIT_FILE, e); 1246 } 1247 } 1248 1249 @Override 1250 protected void createArchiveDatabaseStartScript(File dir) { 1251 // Ignore if no archive database directory has been defined. 1252 String dbDir = machineParameters.getArchiveDatabaseDirValue(); 1253 if (dbDir.isEmpty()) { 1254 return; 1255 } 1256 1257 // TODO NOT SUPPORTED! 1258 System.err.println("An Admin Database is not supported on a windows " 1259 + "machine. Please fix your deploy configuration."); 1260 } 1261 1262 @Override 1263 protected void createArchiveDatabaseKillScript(File dir) { 1264 // Ignore if no archive database directory has been defined. 1265 String dbDir = machineParameters.getArchiveDatabaseDirValue(); 1266 if (dbDir.isEmpty()) { 1267 return; 1268 } 1269 1270 // TODO NOT SUPPORTED! 1271 System.err.println("An Admin Database is not supported on a windows " 1272 + "machine. Please fix your deploy configuration."); 1273 } 1274 1275 @Override 1276 protected void createHarvestDatabaseStartScript(File dir) { 1277 // Ignore if no harvest database directory has been defined. 1278 String dbDir = machineParameters.getHarvestDatabaseDirValue(); 1279 if (dbDir.isEmpty()) { 1280 return; 1281 } 1282 1283 // TODO NOT SUPPORTED! 1284 System.err.println("An Harvest Database is not supported on a windows " 1285 + "machine. Please fix your deploy configuration."); 1286 } 1287 1288 @Override 1289 protected void createHarvestDatabaseKillScript(File dir) { 1290 // Ignore if no harvest database directory has been defined. 1291 String dbDir = machineParameters.getHarvestDatabaseDirValue(); 1292 if (dbDir.isEmpty()) { 1293 return; 1294 } 1295 1296 // TODO NOT SUPPORTED! 1297 System.err.println("An Harvest Database is not supported on a windows " 1298 + "machine. Please fix your deploy configuration."); 1299 } 1300 1301 @Override 1302 protected void createHarvestDatabaseUpdateScript(File machineDirectory, boolean forceCreate) { 1303 // Ignore if no harvest database directory has been defined. 1304 String dbDir = machineParameters.getHarvestDatabaseDirValue(); 1305 if (dbDir.isEmpty()) { 1306 return; 1307 } 1308 1309 System.err.println("An Harvest Database is not supported on a windows " 1310 + "machine. Please fix your deploy configuration."); 1311 } 1312 1313}