1 /**
2 * AUTOHIT 2003
3 * Copyright Erich P Gatejen (c) 1989,1997,2003,2004
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Additional license information can be found in the documentation.
19 * @author Erich P Gatejen
20 */
21 package autohit.common.deployment;
22
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileReader;
26 import java.util.StringTokenizer;
27
28 import org.apache.commons.collections.ExtendedProperties;
29
30 import autohit.common.AutohitProperties;
31 import autohit.common.Constants;
32 import autohit.common.Utils;
33
34 /**
35 * A deployment manager. It will handle configuration, installation, and checkpointing.
36 *
37 * @author Erich P. Gatejen
38 * @version 1.0
39 * <i>Version History</i>
40 * <code>EPG - Initial - 25Apr03
41 *
42 */
43 public class DeploymentConfigure {
44
45 /**
46 * Command system
47 */
48 public ExtendedProperties props;
49
50 /**
51 * Default constructor.
52 */
53 public DeploymentConfigure() throws Exception {
54
55 }
56
57 /**
58 * Checkpoint the system
59 * @param name checkpoint name
60 * @param root directory root
61 * @param cf configuration file
62 * @param special unlock factory. ALWAYS use FALSE
63 * @return true if successful, false if there is an error
64 */
65 public boolean checkpoint(
66 String name,
67 String root,
68 String cf,
69 boolean special) {
70
71 String[] currentLine;
72 String lf;
73 File lFile;
74 int count = 0;
75 int lineCount = 0;
76
77 // Is it trying to checkpoint to the factory settings?
78 if ((special == false)
79 && (name.equals(AutohitProperties.vFACTORY_STORE))) {
80 System.out.println(
81 "You may not checkpoint to the factory settings. Use a checkpoint name other than 'factory'.");
82 return false;
83 }
84
85 String configPath =
86 new String(root + AutohitProperties.vCONFIG_ROOT + name + "/");
87
88 // See if already saved.
89 File fdpath = new File(configPath);
90 if (fdpath.exists()) {
91 System.out.println(
92 "There is already a " + name + " checkpoint set.");
93 System.out.println("You can use the delete command to remove it.");
94 return false;
95 }
96
97 // Set the config file
98 if (cf == null) {
99 cf = AutohitProperties.vDEFAULT_CHECKPOINT;
100 }
101 lf = new String(root + AutohitProperties.vCONFIG_ROOT + cf);
102
103 // Get to work
104 try {
105 // Make the dir
106 fdpath.mkdirs();
107
108 // Open config file
109 lFile = new File(lf);
110 BufferedReader inBR = new BufferedReader(new FileReader(lFile));
111
112 // example line: n bin/default.prop factory/standard/default.prop
113 currentLine = parseConfigLine(inBR);
114 while (currentLine != null) {
115 lineCount++;
116 switch (currentLine[0].charAt(0)) {
117
118 case Constants.CONFIG_DIR :
119 System.out.println(
120 Utils.copyDir(
121 root + "/" + currentLine[1],
122 configPath + Integer.toString(count),
123 false));
124 count++;
125 break;
126
127 case Constants.CONFIG_COMMENT :
128 // ignore
129 break;
130
131 case Constants.CONFIG_CHKPNT :
132 case Constants.CONFIG_CONFIG_YES :
133 case Constants.CONFIG_CONFIG_NO :
134 System.out.println(
135 Utils.copy(
136 root + "/" + currentLine[1],
137 configPath + Integer.toString(count)));
138 count++;
139 break;
140
141 default :
142 System.out.println(
143 "Bad command. Line #"
144 + lineCount
145 + ". Command ="
146 + currentLine[0].charAt(0));
147 }
148 currentLine = parseConfigLine(inBR);
149 }
150
151 // Move the config file
152 inBR.close();
153 System.out.println(
154 Utils.copy(lf, configPath + AutohitProperties.vCONFIG_FILE));
155
156 } catch (Exception e) {
157 System.out.println("CHECKPOINT failed!");
158 e.printStackTrace();
159 return false;
160 }
161
162 System.out.println("CHECKPOINT is done.");
163 return true;
164 }
165
166 /**
167 * Delete a checkpoint
168 * @param name checkpoint name
169 * @param root directory root
170 * @return true if successful, false if there is an error
171 */
172 public boolean delete(String name, String root) {
173
174 String[] currentLine;
175 String lf;
176 File lFile;
177 int count = 0;
178 int lineCount = 0;
179
180 String configPath =
181 new String(root + AutohitProperties.vCONFIG_ROOT + name);
182
183 // Is it trying to remove the factory settings?
184 if (name.equals(AutohitProperties.vFACTORY_STORE)) {
185 System.out.println("You may not delete the factory settings.");
186 }
187
188 // See if already saved.
189 File fdpath = new File(configPath);
190 if (!fdpath.exists()) {
191 System.out.println("Checkpoint set does not exist.");
192 return false;
193 }
194
195 System.out.println(Utils.wipeDir(configPath));
196 System.out.println("DELETE is done. Check messages for errors.");
197 return true;
198 }
199
200 /**
201 * Restore a checkpoint
202 * @param name checkpoint name
203 * @param root directory root
204 * @param wipe destructive restore
205 * @return true if successful, false if there is an error
206 */
207 public boolean restore(String name, String root, boolean wipe) {
208
209 String[] currentLine;
210 String lf;
211 File fdfile;
212 int count = 0;
213 int lineCount = 0;
214 BufferedReader inBR;
215
216 String configPath =
217 new String(root + AutohitProperties.vCONFIG_ROOT + name + "/");
218 String configFile =
219 new String(configPath + AutohitProperties.vCONFIG_FILE);
220
221 // See if it is there and get the configuration file
222 try {
223
224 fdfile = new File(configPath);
225 if (!fdfile.exists())
226 throw new Exception();
227 inBR = new BufferedReader(new FileReader(fdfile));
228
229 } catch (Exception e) {
230 System.out.println(
231 "Checkpoint does not exist or is invalid for " + name);
232 return false;
233 }
234
235 // Get to work
236 try {
237
238 // example line: n bin/default.prop factory/standard/default.prop
239 currentLine = parseConfigLine(inBR);
240 while (currentLine != null) {
241 lineCount++;
242 switch (currentLine[1].charAt(0)) {
243
244 case Constants.CONFIG_DIR :
245 System.out.println(
246 Utils.copyDir(
247 configPath + Integer.toString(count),
248 root + "/" + currentLine[1],
249 wipe));
250 count++;
251 break;
252
253 case Constants.CONFIG_COMMENT :
254 // ignore
255 break;
256
257 case Constants.CONFIG_CHKPNT :
258 case Constants.CONFIG_CONFIG_YES :
259 case Constants.CONFIG_CONFIG_NO :
260 System.out.println(
261 Utils.copy(
262 root + "/" + currentLine[1],
263 configPath + Integer.toString(count)));
264 count++;
265 break;
266
267 default :
268 System.out.println(
269 "Bad command. Line #"
270 + lineCount
271 + ". Command ="
272 + currentLine[1].charAt(0));
273 }
274 currentLine = parseConfigLine(inBR);
275 }
276
277 } catch (Exception e) {
278 System.out.println("RESTORE failed!");
279 e.printStackTrace();
280 return false;
281 }
282 System.out.println("RESTORE is done.");
283 return true;
284 }
285
286 /**config config [config name] [root] [prop file]
287 * Process a configuration
288 * @param config config file name
289 * @param root directory root
290 * @param vars variable replacement set. a properties file.
291 * @return true if successful, false if there is an error
292 */
293 public boolean configure(String config, String root, String vars) {
294
295 ExtendedProperties varprops;
296
297 // Get variables file and load into varprops
298 String varPath = new String(root + AutohitProperties.vVAR_ROOT + vars);
299 File varFile = new File(varPath);
300 if (!varFile.exists()) {
301 System.out.println(
302 "Configuration values file does not exist= "
303 + vars
304 + ". It should be under the /etc directory.");
305 return false;
306 }
307 try {
308 varprops = new ExtendedProperties(varPath);
309 } catch (Exception e) {
310 System.out.println("Configuration values file is unreadable.");
311 return false;
312 }
313 return configure(config, root, varprops);
314 }
315
316 /**config config [config name] [root] [prop file]
317 * Process a configuration
318 * @param config config file name
319 * @param root directory root
320 * @param varprops an ExtendedProperties set of configuration name/values.
321 * @return true if successful, false if there is an error
322 */
323 public boolean configure(
324 String config,
325 String root,
326 ExtendedProperties varprops) {
327
328 String[] currentLine;
329 String lf;
330 File fdfile;
331 int count = 0;
332 int lineCount = 0;
333 BufferedReader inBR;
334
335 String configPath;
336 String configPathFile;
337 File fConfigFile;
338
339 // See if it is there and get the configuration file
340 try {
341 // try the root
342 configPath =
343 new String(
344 root + AutohitProperties.vCONFIG_ROOT + config + "/");
345 configPathFile =
346 new String(configPath + AutohitProperties.vCONFIG_FILE);
347 fConfigFile = new File(configPathFile);
348 if (!fConfigFile.exists()) {
349 // see if there are any hanger-ons
350 configPathFile = new String(configPath + config);
351 fConfigFile = new File(configPathFile);
352 if (!fConfigFile.exists())
353 throw new Exception();
354 }
355 inBR = new BufferedReader(new FileReader(fConfigFile));
356 } catch (Exception e) {
357 System.out.println(
358 "Configuration descriptor is invalid for " + config);
359 return false;
360 }
361
362 // Get to work
363 try {
364
365 // example line: n bin/default.prop factory/standard/default.prop
366 currentLine = parseConfigLine(inBR);
367 while (currentLine != null) {
368 lineCount++;
369 System.out.println("linecount="+lineCount+" count=" + count + " line="+ currentLine[0]);
370 switch (currentLine[0].charAt(0)) {
371
372 case Constants.CONFIG_DIR :
373 System.out.println(
374 Utils.copyDir(
375 configPath + Integer.toString(count),
376 root + "/" + currentLine[1],
377 false));
378 count++;
379 break;
380
381 case Constants.CONFIG_COMMENT :
382 case Constants.CONFIG_CHKPNT :
383 // ignore
384 break;
385
386 case Constants.CONFIG_CONFIG_YES :
387 System.out.println(
388 Utils.merge(
389 configPath + Integer.toString(count),
390 root + "/" + currentLine[1],
391 varprops));
392 count++;
393 break;
394
395 case Constants.CONFIG_CONFIG_NO :
396 System.out.println(
397 Utils.copy(
398 configPath + Integer.toString(count),
399 root + "/" + currentLine[1]));
400 count++;
401 break;
402
403 default :
404 System.out.println(
405 "Bad command. Line #"
406 + lineCount
407 + ". Command ="
408 + currentLine[0].charAt(0));
409 }
410 currentLine = parseConfigLine(inBR);
411 }
412
413 } catch (Exception e) {
414 System.out.println("CONFIGURE failed!");
415 e.printStackTrace();
416 return false;
417 }
418 System.out.println("CONFIGURE is done.");
419 return true;
420 }
421
422 /**
423 * Parse the config line
424 */
425 private String[] parseConfigLine(BufferedReader inR) {
426
427 String t[] = new String[3];
428 String working = null;
429 StringTokenizer st;
430
431 try {
432
433 working = inR.readLine();
434 while ((working.length() == 0)
435 || (working.charAt(0) == '#')
436 || (!Character.isLetter(working.charAt(0)))) {
437 working = inR.readLine();
438 }
439
440 // Working should be a valid line
441 try {
442
443 st = new StringTokenizer(working);
444 t[0] = st.nextToken();
445 t[1] = st.nextToken();
446 // the third field doesn't matter for checkpointing
447 try {
448 t[2] = st.nextToken();
449 } catch (Exception e) {
450 t[2] = null;
451 }
452
453 } catch (Exception e) {
454 System.out.println("BAD line in Files:\n" + working);
455 throw e;
456 }
457
458 } catch (Exception e) {
459 // Quit for ANY exception
460 return null;
461 }
462
463 return t;
464 }
465
466 /**
467 * Object main
468 */
469 public void go(String[] args) {
470
471 char cmd = args[0].charAt(0);
472 switch (cmd) {
473 case 'S' :
474 case 's' :
475 if (args.length == 4) {
476 checkpoint(args[1], args[2], args[3], false);
477 } else if (args.length == 3) {
478 checkpoint(args[1], args[2], null, false);
479 } else {
480 System.out.println("ERROR: Bad number of parameters.");
481 usage();
482 }
483 break;
484
485 case 'F' :
486 case 'f' :
487 System.out.println("BUILD FACTORY SETTINGS");
488 // CHECKPOINT THE FACTORY
489 // YOU SHOULDN'T DO THIS! IT'S FOR THE BUILD SYSTEM
490 // The command is "config factory PLEASE [root]" (cases sensitive)
491 if ((args.length == 3) && (args[1].charAt(0) == 'P')) {
492 checkpoint(
493 AutohitProperties.vFACTORY_STORE,
494 args[2],
495 AutohitProperties.vDEFAULT_CHECKPOINT,
496 true);
497 } else {
498 System.out.println("ERROR: Unknown command.");
499 usage();
500 }
501 break;
502
503 case 'R' :
504 case 'r' :
505 if (args.length == 3) {
506 restore(args[1], args[2], true);
507 } else {
508 System.out.println("ERROR: Bad number of parameters.");
509 usage();
510 }
511 break;
512 case 'M' :
513 case 'm' :
514 if (args.length == 3) {
515 restore(args[1], args[2], false);
516 } else {
517 System.out.println("ERROR: Bad number of parameters.");
518 usage();
519 }
520 break;
521 case 'D' :
522 case 'd' :
523 if (args.length == 3) {
524 delete(args[1], args[2]);
525 } else {
526 System.out.println("ERROR: Bad number of parameters.");
527 usage();
528 }
529
530 break;
531 case 'c' :
532 case 'C' :
533 if (args.length != 4) {
534 System.out.println("ERROR: Bad parameters.");
535 } else {
536 configure(args[1], args[2], args[3]);
537 }
538 break;
539
540 case 'H' :
541 case 'h' :
542 case '?' :
543 case '-' :
544 usage();
545 break;
546
547 default :
548 System.out.println("ERROR: Unknown command.");
549 usage();
550 break;
551 }
552 }
553
554 // Usage
555 public void usage() {
556 System.out.println("Deployment Configuration for Autohit (2003):");
557 System.out.println(" config config [name] [root] [var file]");
558 System.out.println(" config save [name] [root] (config file)");
559 System.out.println(" ...... save a checkpoint by name.");
560 System.out.println(" config delete [name] [root]");
561 System.out.println(" config restore [name] [root]");
562 System.out.println(
563 " ...... restore a checkpoint. It is destructive.");
564 System.out.println(" config merge [name] [root]");
565 System.out.println(
566 " ...... merge a checkpoint. It will only overwrite named files.");
567 System.out.println(
568 " The configuration called 'factory' will restore to the system to");
569 System.out.println(" ...... out-of-the-box.");
570 }
571
572 /**
573 * main interface
574 */
575 public static void main(String[] args) {
576
577 try {
578 DeploymentConfigure me = new DeploymentConfigure();
579
580 // handle arguments
581 if (args.length == 0) {
582 System.out.println("Huh? What did you want me to do?");
583 me.usage();
584 return;
585 }
586
587 me.go(args);
588 } catch (Exception e) {
589 e.printStackTrace();
590 }
591 }
592 }
|