View Javadoc

1   /*
2    * JBoss, Home of Professional Open Source.
3    * Copyright 2013, Red Hat Middleware LLC, and individual contributors
4    * as indicated by the @author tags. See the copyright.txt file in the
5    * distribution for a full listing of individual contributors.
6    *
7    * This is free software; you can redistribute it and/or modify it
8    * under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */
22  package org.redhat.vmtruckloader.service;
23  
24  import static org.redhat.vmtruckloader.util.CSVUtils.turnLineIntoSpec;
25  import static org.redhat.vmtruckloader.util.CSVUtils.updateLineInCsvFile;
26  import static org.redhat.vmtruckloader.util.ExecUtils.COMMAND_LINE_SEPARATOR;
27  import static org.redhat.vmtruckloader.util.ExecUtils.executeScriptAndReturnsResult;
28  import static org.redhat.vmtruckloader.util.StringUtil.checkIfStringValid;
29  
30  import java.io.File;
31  import java.util.ArrayList;
32  import java.util.List;
33  import java.util.Properties;
34  
35  import org.jboss.weld.environment.se.Weld;
36  import org.jboss.weld.environment.se.WeldContainer;
37  import org.redhat.vmtruckloader.service.cli.Arguments;
38  import org.redhat.vmtruckloader.util.FileUtils;
39  import org.redhat.vmtruckloader.util.StringUtil;
40  import org.redhat.vmtruckloader.util.URLUtils;
41  
42  import com.beust.jcommander.JCommander;
43  import com.beust.jcommander.ParameterException;
44  
45  /**
46   * Main class for this tool:
47   * Process the arguments, displays help text, and ensure the program
48   * exit with the appropriate error code
49   *
50   * @author Romain Pelisse - <belaran@redhat.com>
51   *
52   */
53  public class VmTruckLoader {
54  
55  	private static final String PROG_NAME = "vm-set-up";
56  
57  	private static final int INVALID_COMMAND_INPUT = 1;
58  	private static final int INPUT_ERROR_NOFILE_NORLINE = 2;
59  	private static final int PROGRAM_THROWN_EXCEPTION = 3;
60  
61  
62  	private static final boolean STACKTRACE_ENABLED = false;
63  
64  	public static void runWithCatch(String[] args) {
65  		try {
66  			run(args);
67  		} catch ( Throwable t ) {
68  			consolePrint(t.getMessage());
69  			if ( t.getCause() != null )
70  				consolePrint(t.getCause().getMessage());
71  			System.exit(PROGRAM_THROWN_EXCEPTION);
72  		}
73  	}
74  
75  	public static void run(String[] args) {
76  		Arguments arguments = setDefaultValues(validateArgs(VmTruckLoader.extractParameters(args)));
77  
78  		List<MachineSpecification> specs;
79  		if ( arguments.getFile() != null )
80  			specs = turnFileIntoSpec(arguments.getFile());
81  		else {
82  			specs = new ArrayList<MachineSpecification>();
83  			specs.add(turnLineIntoSpec(arguments.getLine()));
84  		}
85  
86  		Properties props = System.getProperties();
87  		props.put("org.slf4j.simpleLogger.defaultLogLevel", "ERROR");
88  		System.setProperties(props);
89  
90  		WeldContainer weld = new Weld().initialize();
91  		MachineService machineService = weld.instance().select(MachineService.class).get();
92  		machineService.setConnectionData(arguments.getUsername(), arguments.getPassword(), URLUtils.createUrl(arguments.getVCenterURl()));
93  
94  		if ( specs.isEmpty() ) {
95  			consolePrint("No machine specification found.");
96  			System.exit(0);
97  		}
98  
99  		validatePostExecScript(arguments.getPostExec());
100 
101 		for ( MachineSpecification spec : specs ) {
102 			switch (arguments.getAction()) {
103 			case CREATE:
104 				StringUtil.checkIfStringValid(arguments.getTemplateName(),"The template name is required for action " + arguments.getAction());
105 				consolePrint("Creating machine " + spec.getVmName() + " ...");
106 				spec = machineService.cloneMachine(arguments.getTemplateName(), spec);
107 				spec.setMAC("@MAC");
108 				consolePrint("- machine " + spec.getVmName() + " has been successfully created." );
109 				consolePrint("-      with @MAC: " +	spec.getMAC());
110                 if ( arguments.getFile() != null )
111 				    updateLineInCsvFile(arguments.getFile().getAbsolutePath(), spec);
112 				runPostExecScriptIfAny(arguments.getPostExec(), spec);
113 				break;
114 			case DELETE:
115 				consolePrint("Deleting VM: " + spec.getHostname());
116 				machineService.deleteMachine(spec.getHostname());
117 				break;
118 			case START:
119 				consolePrint("Starting VM: " + spec.getHostname());
120 				machineService.startMachine(spec.getHostname());
121 				break;
122 			case STOP:
123 				consolePrint("Stopping VM: " + spec.getHostname());
124 				machineService.stopMachine(spec.getHostname());
125 				break;
126 			case RESTART:
127 				consolePrint("Restarting VM: " + spec.getHostname());
128 				machineService.stopMachine(spec.getHostname());
129 				machineService.startMachine(spec.getHostname());
130 				break;
131 			case EDIT:
132 				consolePrint("Edit VM: " + spec.getHostname());
133 				machineService.editMachine(spec);
134 				break;
135 			default:
136 				throw new IllegalStateException("Unrecognized action requested:" + arguments.getAction());
137 			}
138 		}
139 	}
140 
141 	private static void runPostExecScriptIfAny(File postExec,
142 			MachineSpecification spec) {
143 		if ( postExec == null) return;
144 		for ( String line : executeScriptAndReturnsResult(buildCommandLine(postExec,spec)))
145 			consolePrint(line);
146 	}
147 
148 	private static String buildCommandLine(File postExec,
149 			MachineSpecification spec) {
150 
151 		return postExec.getAbsolutePath() + COMMAND_LINE_SEPARATOR + spec.getHostname() + COMMAND_LINE_SEPARATOR +
152 				spec.getMAC() + COMMAND_LINE_SEPARATOR + spec.getRole() + COMMAND_LINE_SEPARATOR + spec.getRole();
153 	}
154 
155 	private static void validatePostExecScript(File postExec) {
156 		if ( postExec == null) return;
157 
158 		if ( ! postExec.exists() )
159 	      throw new IllegalArgumentException(postExec.getAbsolutePath() + " does not exist, and therefore can't be run ");
160 
161 		if ( ! postExec.canExecute() )
162 		      throw new IllegalArgumentException(postExec.getAbsolutePath() + " is not executable, and therefore can't be run ");
163 	}
164 
165 	private static List<MachineSpecification> turnFileIntoSpec(File file) {
166 		List<String> lines =  FileUtils.readLineByLine(file);
167 		List<MachineSpecification> specs = new ArrayList<MachineSpecification>(lines.size());
168 		for ( String line : lines ) {
169 			specs.add(turnLineIntoSpec(line));
170 		}
171 		return specs;
172 	}
173 
174 	public static void main(String[] args) {
175 		if ( STACKTRACE_ENABLED ) runWithCatch(args); else run(args);
176 	}
177 
178 	private static Arguments validateArgs(Arguments arguments) {
179 		checkIfStringValid(arguments.getUsername(),"Username can't be 'null' or 'empty'");
180 		checkIfStringValid(arguments.getPassword(),"Password can't be 'null' or 'empty'");
181 		checkIfStringValid(arguments.getVCenterURl(),"vCenter URL can't be 'null' or 'empty'");
182 		return arguments;
183 	}
184 
185 	private static Arguments setDefaultValues(Arguments arguments) {
186 		return arguments;
187 	}
188 
189 	private static void consolePrint(String string, boolean printCarriageReturn) {
190 		if ( printCarriageReturn )
191 			System.out.println(string);	//NOPMD
192 		else
193 			System.out.print(string);	//NOPMD
194 	}
195 
196 	private static void consolePrint(String string) {
197 		consolePrint(string, true);
198 	}
199 
200 	private static Arguments extractParameters(String[] args) {
201 		Arguments arguments = new Arguments();
202 		JCommander jcommander = null;
203 		try {
204 			jcommander = new JCommander(arguments, args);
205 			jcommander.setProgramName(PROG_NAME);
206 			if (arguments.isHelp()) {
207 				jcommander.usage();
208 				System.exit(0);
209 			}
210 
211 			if ( arguments.getLine() == null && arguments.getFile() == null ) {
212 				consolePrint(PROG_NAME + " requires either a line or a file:");
213 				jcommander.usage();
214 				System.exit(INPUT_ERROR_NOFILE_NORLINE);
215 			}
216 
217 		} catch (ParameterException e) {
218 			System.out.println(e.getMessage());
219 			System.exit(INVALID_COMMAND_INPUT);
220 		}
221 		return arguments;
222 	}
223 }