/* * JBoss, Home of Professional Open Source. * Copyright 2013, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.redhat.vmtruckloader.service; import static org.redhat.vmtruckloader.util.CSVUtils.turnLineIntoSpec; import static org.redhat.vmtruckloader.util.CSVUtils.updateLineInCsvFile; import static org.redhat.vmtruckloader.util.ExecUtils.COMMAND_LINE_SEPARATOR; import static org.redhat.vmtruckloader.util.ExecUtils.executeScriptAndReturnsResult; import static org.redhat.vmtruckloader.util.StringUtil.checkIfStringValid; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Properties; import org.jboss.weld.environment.se.Weld; import org.jboss.weld.environment.se.WeldContainer; import org.redhat.vmtruckloader.service.cli.Arguments; import org.redhat.vmtruckloader.util.FileUtils; import org.redhat.vmtruckloader.util.StringUtil; import org.redhat.vmtruckloader.util.URLUtils; import com.beust.jcommander.JCommander; import com.beust.jcommander.ParameterException; /** * Main class for this tool: * Process the arguments, displays help text, and ensure the program * exit with the appropriate error code * * @author Romain Pelisse - <belaran@redhat.com> * */ public class VmTruckLoader { private static final String PROG_NAME = "vm-set-up"; private static final int INVALID_COMMAND_INPUT = 1; private static final int INPUT_ERROR_NOFILE_NORLINE = 2; private static final int PROGRAM_THROWN_EXCEPTION = 3; private static final boolean STACKTRACE_ENABLED = false; public static void runWithCatch(String[] args) { try { run(args); } catch ( Throwable t ) { consolePrint(t.getMessage()); if ( t.getCause() != null ) consolePrint(t.getCause().getMessage()); System.exit(PROGRAM_THROWN_EXCEPTION); } } public static void run(String[] args) { Arguments arguments = setDefaultValues(validateArgs(VmTruckLoader.extractParameters(args))); List<MachineSpecification> specs; if ( arguments.getFile() != null ) specs = turnFileIntoSpec(arguments.getFile()); else { specs = new ArrayList<MachineSpecification>(); specs.add(turnLineIntoSpec(arguments.getLine())); } Properties props = System.getProperties(); props.put("org.slf4j.simpleLogger.defaultLogLevel", "ERROR"); System.setProperties(props); WeldContainer weld = new Weld().initialize(); MachineService machineService = weld.instance().select(MachineService.class).get(); machineService.setConnectionData(arguments.getUsername(), arguments.getPassword(), URLUtils.createUrl(arguments.getVCenterURl())); if ( specs.isEmpty() ) { consolePrint("No machine specification found."); System.exit(0); } validatePostExecScript(arguments.getPostExec()); for ( MachineSpecification spec : specs ) { switch (arguments.getAction()) { case CREATE: StringUtil.checkIfStringValid(arguments.getTemplateName(),"The template name is required for action " + arguments.getAction()); consolePrint("Creating machine " + spec.getVmName() + " ..."); spec = machineService.cloneMachine(arguments.getTemplateName(), spec); spec.setMAC("@MAC"); consolePrint("- machine " + spec.getVmName() + " has been successfully created." ); consolePrint("- with @MAC: " + spec.getMAC()); if ( arguments.getFile() != null ) updateLineInCsvFile(arguments.getFile().getAbsolutePath(), spec); runPostExecScriptIfAny(arguments.getPostExec(), spec); break; case DELETE: consolePrint("Deleting VM: " + spec.getHostname()); machineService.deleteMachine(spec.getHostname()); break; case START: consolePrint("Starting VM: " + spec.getHostname()); machineService.startMachine(spec.getHostname()); break; case STOP: consolePrint("Stopping VM: " + spec.getHostname()); machineService.stopMachine(spec.getHostname()); break; case RESTART: consolePrint("Restarting VM: " + spec.getHostname()); machineService.stopMachine(spec.getHostname()); machineService.startMachine(spec.getHostname()); break; case EDIT: consolePrint("Edit VM: " + spec.getHostname()); machineService.editMachine(spec); break; default: throw new IllegalStateException("Unrecognized action requested:" + arguments.getAction()); } } } private static void runPostExecScriptIfAny(File postExec, MachineSpecification spec) { if ( postExec == null) return; for ( String line : executeScriptAndReturnsResult(buildCommandLine(postExec,spec))) consolePrint(line); } private static String buildCommandLine(File postExec, MachineSpecification spec) { return postExec.getAbsolutePath() + COMMAND_LINE_SEPARATOR + spec.getHostname() + COMMAND_LINE_SEPARATOR + spec.getMAC() + COMMAND_LINE_SEPARATOR + spec.getRole() + COMMAND_LINE_SEPARATOR + spec.getRole(); } private static void validatePostExecScript(File postExec) { if ( postExec == null) return; if ( ! postExec.exists() ) throw new IllegalArgumentException(postExec.getAbsolutePath() + " does not exist, and therefore can't be run "); if ( ! postExec.canExecute() ) throw new IllegalArgumentException(postExec.getAbsolutePath() + " is not executable, and therefore can't be run "); } private static List<MachineSpecification> turnFileIntoSpec(File file) { List<String> lines = FileUtils.readLineByLine(file); List<MachineSpecification> specs = new ArrayList<MachineSpecification>(lines.size()); for ( String line : lines ) { specs.add(turnLineIntoSpec(line)); } return specs; } public static void main(String[] args) { if ( STACKTRACE_ENABLED ) runWithCatch(args); else run(args); } private static Arguments validateArgs(Arguments arguments) { checkIfStringValid(arguments.getUsername(),"Username can't be 'null' or 'empty'"); checkIfStringValid(arguments.getPassword(),"Password can't be 'null' or 'empty'"); checkIfStringValid(arguments.getVCenterURl(),"vCenter URL can't be 'null' or 'empty'"); return arguments; } private static Arguments setDefaultValues(Arguments arguments) { return arguments; } private static void consolePrint(String string, boolean printCarriageReturn) { if ( printCarriageReturn ) System.out.println(string); //NOPMD else System.out.print(string); //NOPMD } private static void consolePrint(String string) { consolePrint(string, true); } private static Arguments extractParameters(String[] args) { Arguments arguments = new Arguments(); JCommander jcommander = null; try { jcommander = new JCommander(arguments, args); jcommander.setProgramName(PROG_NAME); if (arguments.isHelp()) { jcommander.usage(); System.exit(0); } if ( arguments.getLine() == null && arguments.getFile() == null ) { consolePrint(PROG_NAME + " requires either a line or a file:"); jcommander.usage(); System.exit(INPUT_ERROR_NOFILE_NORLINE); } } catch (ParameterException e) { System.out.println(e.getMessage()); System.exit(INVALID_COMMAND_INPUT); } return arguments; } }