/*
* Copyright 1999-2008 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.globus.workspace.cloud.client;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.apache.axis.types.URI;
import org.apache.commons.cli.ParseException;
import org.globus.gsi.GlobusCredential;
import org.globus.workspace.client_common.BaseClient;
import org.globus.workspace.client_core.ExecutionProblem;
import org.globus.workspace.client_core.ExitNow;
import org.globus.workspace.client_core.ParameterProblem;
import org.globus.workspace.client_core.actions.Status_QueryAll;
import org.globus.workspace.client_core.print.PrCodes;
import org.globus.workspace.client_core.repr.Workspace;
import org.globus.workspace.client_core.utils.NimbusCredential;
import org.globus.workspace.cloud.client.cluster.ClusterMember;
import org.globus.workspace.cloud.client.cluster.ClusterUtil;
import org.globus.workspace.cloud.client.cluster.KnownHostsTask;
import org.globus.workspace.cloud.client.security.CertUtil;
import org.globus.workspace.cloud.client.security.SecurityPrinter;
import org.globus.workspace.cloud.client.security.TrustedCAs;
import org.globus.workspace.cloud.client.util.CloudClientUtil;
import org.globus.workspace.cloud.client.util.DeploymentXMLUtil;
import org.globus.workspace.cloud.client.util.ExecuteUtil;
import org.globus.workspace.cloud.client.util.RepositoryInterface;
import org.globus.workspace.cloud.client.util.FileListing;
import org.globus.workspace.cloud.client.util.HistoryUtil;
import org.globus.workspace.cloud.client.util.MetadataXMLUtil;
import org.globus.workspace.common.SecurityUtil;
import org.globus.workspace.common.client.CLIUtils;
import org.globus.workspace.common.client.CommonPrint;
import org.globus.workspace.common.print.Print;
import org.globus.workspace.common.print.PrintOpts;
import org.globus.workspace.status.client.WorkspaceStatusClient;
import org.globus.wsrf.impl.security.authorization.HostAuthorization;
import org.globus.wsrf.impl.security.authorization.IdentityAuthorization;
import org.globus.wsrf.utils.AddressingUtils;
import org.nimbustools.ctxbroker.generated.gt4_0.description.Cloudcluster_Type;
import org.nimbustools.messaging.gt4_0.common.CommonUtil;
import org.nimbustools.messaging.gt4_0.generated.metadata.VirtualWorkspace_Type;
import org.nimbustools.messaging.gt4_0.generated.negotiable.WorkspaceDeployment_Type;
import org.nimbustools.messaging.gt4_0.generated.status.WorkspaceStatusFault;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.security.NoSuchAlgorithmException;
import java.util.List;
public class CloudClient {
// -------------------------------------------------------------------------
// STATIC VARIABLES
// -------------------------------------------------------------------------
public static final int SUCCESS_EXIT_CODE = 0;
public static final int COMMAND_LINE_EXIT_CODE = 1;
public static final int APPLICATION_EXIT_CODE = 2;
public static final int UNKNOWN_ERROR_EXIT_CODE = 3;
// -------------------------------------------------------------------------
// INSTANCE VARIABLES
// -------------------------------------------------------------------------
private AllArgs args;
// set if handle is a cluster handle
private boolean isClusterHandle;
private ExecuteUtil executeUtil = new ExecuteUtil();
private final Print print;
/* derived */
private GlobusCredential x509Used;
private String specificEPRpath;
private String[] trustedCertDirs;
private String workspaceFactoryURL;
private EndpointReferenceType statusServiceEPR;
private String newUnpropTargetURL;
private ClusterMember[] clusterMembers;
private URI kernelURI;
private RepositoryInterface repoUtil;
// -------------------------------------------------------------------------
// CONSTRUCTORS
// -------------------------------------------------------------------------
/**
* @param pr must be non-null
*/
public CloudClient(Print pr) {
if (pr == null) {
throw new IllegalArgumentException("print may not be null");
}
this.print = pr;
}
// -------------------------------------------------------------------------
// ENTRY POINTS
// -------------------------------------------------------------------------
// null means all
public static int[] getOptInPrCodes() {
final int[] optOuts = { PrCodes.OPTIONALPARAM__FILE_READ,
PrCodes.DEPREQ__FILE_READ,
PrCodes.METADATA__FILE_READ,
PrCodes.SSH__FILE_READ,
PrCodes.LISTENER_STATECHANGE__INSTANCE_STATE_CHANGE,
PrCodes.CREATE__EPRFILE_WRITES,
PrCodes.CREATE__INSTANCE_ID_PRINT,
PrCodes.CREATE__INSTANCE_CREATING_INIITIAL_DURATION,
PrCodes.CREATE__INSTANCE_CREATING_NET_ASSOCIATION,
PrCodes.CREATE__INSTANCE_CREATING_NET_BROADCAST,
PrCodes.CREATE__INSTANCE_CREATING_NET_GATEWAY,
PrCodes.CREATE__INSTANCE_CREATING_NET_MAC,
PrCodes.CREATE__INSTANCE_CREATING_NET_MASK,
PrCodes.CREATE__INSTANCE_CREATING_NET_NETWORK,
PrCodes.CREATE__INSTANCE_CREATING_NET_NAME,
PrCodes.CREATE__ENSEMBLE_ID_PRINT,
PrCodes.CREATE__CONTEXT_ID_PRINT,
PrCodes.CREATE__EXTRALINES,
PrCodes.MD_SSH__FILE_READ,
PrCodes.MD_USERDATA__FILE_READ,
PrCodes.LISTENER_TERMINATION__INSTANCE_ID_PRINT,
PrCodes.LISTENER_AUTODESTROY,
PrCodes.CREATE__CTXBROKER_CONTACTINF};
return PrCodes.getAllCodesExcept(optOuts);
}
public static void main(String[] argv) {
// look for debug early, for diagnosing problems with parsing etc.
PrintStream debug = null;
if (CLIUtils.containsDebug(argv)) {
debug = System.err;
}
final PrintOpts pOpts = new PrintOpts(getOptInPrCodes());
final Print print = new Print(pOpts, System.out, System.err, debug);
final int retCode = mainImpl(argv, print);
print.flush();
print.close();
System.exit(retCode);
}
public static int mainImpl(String[] argv, Print pr) {
final CloudClient client = new CloudClient(pr);
// used:
ParameterProblem parameterProblem = null;
ExitNow exitNow = null;
Throwable any = null;
// unused currently:
//Throwable throwable = null;
//ExecutionProblem executionProblem = null;
int retCode;
try {
retCode = _mainImpl(argv, client);
} catch (ExitNow e) {
exitNow = e;
any = e;
retCode = exitNow.exitCode;
} catch (ParameterProblem e) {
parameterProblem = e;
any = e;
retCode = BaseClient.COMMAND_LINE_EXIT_CODE;
} catch (ExecutionProblem e) {
//executionProblem = e;
any = e;
retCode = BaseClient.APPLICATION_EXIT_CODE;
} catch (Throwable t) {
//throwable = t;
any = t;
retCode = BaseClient.UNKNOWN_EXIT_CODE;
}
if (!pr.enabled()) {
// the rest of this method is for printing
return retCode; // *** EARLY RETURN ***
}
if (exitNow != null) {
pr.debugln("[exiting via exitnow system]");
pr.debugln(BaseClient.retCodeDebugStr(retCode));
return retCode; // *** EARLY RETURN ***
}
if (any == null) {
pr.debugln(BaseClient.retCodeDebugStr(retCode));
return retCode; // *** EARLY RETURN ***
}
CommonPrint.printDebugSection(pr, "PROBLEM");
final String message = CommonUtil.genericExceptionMessageWrapper(any);
String err = "Problem: " + message;
if (parameterProblem != null && !pr.useLogging()) {
err += "\nSee help (-h).";
}
pr.errln(err);
pr.debugln("\n");
final String sectionTitle = "STACKTRACE";
CommonPrint.printDebugSection(pr, sectionTitle);
any.printStackTrace(pr.getDebugProxy());
CommonPrint.printDebugSectionEnd(pr, sectionTitle);
pr.debugln("\n");
pr.debugln("Stacktrace was from: " + any.getMessage());
pr.debugln(BaseClient.retCodeDebugStr(retCode));
return retCode;
}
private static int _mainImpl(String[] argv, CloudClient client)
throws ParameterProblem, ExecutionProblem, ExitNow {
// (for development only, to attach a remote debugger etc)
if (CLIUtils.containsDebuggerHang(argv)) {
try {
CLIUtils.hangForInput(client.getPrint());
} catch (IOException e) {
throw new ExecutionProblem("", e);
}
}
CommonPrint.logArgs(argv, client.getPrint());
final AllArgs allArgs = new AllArgs(client.getPrint());
try {
allArgs.intakeCmdlineOptions(argv);
} catch (ParseException e) {
// in all likelihood due to issue with given parameter
throw new ParameterProblem(e.getMessage(), e);
}
try {
allArgs.intakeUserProperties();
allArgs.intakeDefaultProperties();
} catch (IOException e) {
// in all likelihood due to issue with given parameter
throw new ParameterProblem(e.getMessage(), e);
}
client.run(allArgs);
return BaseClient.SUCCESS_EXIT_CODE;
}
// -------------------------------------------------------------------------
// RUN() WRAPPER
// -------------------------------------------------------------------------
/**
* @param allArguments may not be null
* @throws ParameterProblem problem with inputs
* @throws ExecutionProblem problem going through with something
* @throws ExitNow early exit (see source code...)
*/
public void run(AllArgs allArguments) throws ParameterProblem,
ExecutionProblem,
ExitNow {
if (allArguments == null) {
throw new IllegalArgumentException("allArguments may not be null");
}
this.args = allArguments;
String repoType = this.args.getXferType();
if(repoType == null)
{
repoType = "gridftp";
}
this.repoUtil = CloudClientUtil.getRepoUtil(repoType, this.args, this.print);
try {
final String credPath = this.args.getNimbusCertFile();
if (credPath != null) {
NimbusCredential.setNimbusCredentialPath(credPath);
}
final String keyPath = this.args.getNimbusKeyFile();
if (keyPath != null) {
NimbusCredential.setNimbusUnencryptedKeyPath(keyPath);
}
this.parameterCheck();
} catch (Exception e) {
throw new ParameterProblem(e.getMessage(), e);
}
try {
this.runNoParameterCheck();
} finally {
if (this.executeUtil != null) {
this.executeUtil.stopExecutorService();
}
}
}
protected Print getPrint() {
return this.print;
}
// -------------------------------------------------------------------------
// PARAMETER CHECKS
// -------------------------------------------------------------------------
void parameterCheck() throws Exception {
final List actions = this.args.getActions();
if (actions == null || actions.isEmpty()) {
throw new ParameterProblem("Give at least one action.");
}
if (actions.contains(AllArgs.ACTION_HELP) ||
actions.contains(AllArgs.ACTION_EXTRAHELP) ||
actions.contains(AllArgs.ACTION_USAGE)) {
// nothing else matters
return; // *** EARLY RETURN ***
}
if (actions.contains(AllArgs.ACTION_SECURITY_PRINT)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.SECURITY_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_securityPrint();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_TARGET_PRINT)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.PRINT_TARGET_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_targetPrint();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_HASH_PRINT)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.HASH_PRINT_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_hashPrint();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_LIST)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.LIST_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_list();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_TRANSFER)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.TRANSFER_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_transfer();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_DELETE)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.DELETE_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_delete();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_DOWNLOAD)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.DOWNLOAD_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_download();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_SERVICE_PRINT)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.PRINT_SERVICE_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_servicePrint();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_DESTROY)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.DESTROY_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_destroy();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_STATUS_CHECK)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.STATUS_CHECK_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_status();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_ASSOC_QUERY)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.ASSOC_QUERY_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_assocquery();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_SAVE)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.SAVE_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_save();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_RUN)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.RUN_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_run();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_INIT_CONTEXT)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.INIT_CTX_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_initCtx();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (actions.contains(AllArgs.ACTION_PRINT_CTX_STATUS)) {
final String sectionTitle = "PARAMETER CHECK: --" +
Opts.PRINT_CTX_STATUS_OPT_STRING;
CommonPrint.printDebugSection(this.print, sectionTitle);
this.parameterCheck_printContextStatus();
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void parameterCheck_initCtx() throws ParameterProblem {
this._parameterCheck_clusterfile();
this._parameterCheck_initContext();
}
void parameterCheck_list() throws ParameterProblem {
this.repoUtil.paramterCheck(this.args, Opts.LIST_OPT_STRING);
}
void parameterCheck_hashPrint() throws ParameterProblem {
if (this.args.getHashPrintDN() == null) {
throw new ParameterProblem("Hash print requires DN to hash");
}
}
void parameterCheck_securityPrint() throws ParameterProblem {
CloudClientUtil.checkX509Credential("Security printing", this.print);
try {
loadX509BeingUsed();
} catch (Exception e) {
throw new ParameterProblem(e.getMessage());
}
}
void parameterCheck_servicePrint() throws ParameterProblem {
this._checkServiceURL(Opts.PRINT_SERVICE_OPT_STRING);
}
void parameterCheck_destroy() throws ParameterProblem {
if (this.args.getActions().contains(AllArgs.ACTION_RUN)) {
throw new ParameterProblem(
"You cannot create (--" + Opts.RUN_OPT_STRING +
") and destroy in the same invocation");
}
final String actionString = "Terminating";
CloudClientUtil.checkX509Credential(actionString, this.print);
this._translateHandle(actionString);
this._checkSpecificEPR(actionString);
}
void parameterCheck_status() throws ParameterProblem {
if (this.args.getActions().contains(AllArgs.ACTION_RUN)) {
throw new ParameterProblem(
"You cannot create (--" + Opts.RUN_OPT_STRING +
") and run a status check (on a previously" +
"created workspace) in the same invocation");
}
final String actionString = "Checking status";
CloudClientUtil.checkX509Credential(actionString, this.print);
this._translateHandle(actionString);
if (this.args.getHistorySubDir() != null ||
this.args.getEprGivenFilePath() != null) {
this._checkSpecificEPR("Checking status of one workspace");
} else {
this._checkStatusServiceEPR("Checking status of all workspaces");
}
}
void parameterCheck_printContextStatus() throws ParameterProblem {
if (this.args.getActions().contains(AllArgs.ACTION_RUN)) {
throw new ParameterProblem(
"You cannot create (--" + Opts.RUN_OPT_STRING +
") and run print context status (on a previously" +
"created cluster) in the same invocation");
}
final String actionString = "Printing ctx status of each node";
CloudClientUtil.checkX509Credential(actionString, this.print);
this._translateHandle(actionString);
if (this.args.getHistorySubDir() != null ||
this.args.getEprGivenFilePath() != null) {
this._checkSpecificBrokerEPR(actionString);
} else {
throw new ParameterProblem(actionString + " requires either " +
"'--" + Opts.HANDLE_OPT_STRING +
"' or path to specific context EPR file using '--" +
Opts.EPR_FILE_OPT_STRING + '\'');
}
}
void parameterCheck_assocquery() throws ParameterProblem {
final String actionString = "Querying networks";
CloudClientUtil.checkX509Credential(actionString, this.print);
this._checkServiceURL(actionString);
}
void parameterCheck_save() throws ParameterProblem {
if (this.args.getActions().contains(AllArgs.ACTION_RUN)) {
throw new ParameterProblem(
"You cannot create (--" + Opts.RUN_OPT_STRING + ") and " +
"save a previously created workspace in the same invocation");
}
final String actionString = "Saving";
CloudClientUtil.checkX509Credential(actionString, this.print);
this._translateHandle(actionString);
this._checkSpecificEPR(actionString);
this.repoUtil.paramterCheck(this.args, actionString);
final String newname = this.args.getNewname();
if (newname != null) {
this.print.debugln(
"save called with newname '" + newname + "'");
try {
this.newUnpropTargetURL = this.repoUtil.getDerivedImageURL(newname);
} catch (Exception e) {
throw new ParameterProblem("Problem with save's newname '" +
newname + "': " + e.getMessage(), e);
}
} else {
this.print.debugln("save called with no newname");
}
}
void parameterCheck_targetPrint() throws ParameterProblem {
this.repoUtil.paramterCheck(this.args, Opts.TARGETDIR_OPT_STRING);
final String sourcefile = this.args.getSourcefile();
final String name = this.args.getName();
if (sourcefile == null && name == null) {
throw new ParameterProblem(Opts.TARGETDIR_OPT_STRING +
" requires either '" +
Opts.SOURCEFILE_OPT_STRING + "' or '" +
Opts.NAME_OPT_STRING + "'");
}
}
void parameterCheck_transfer() throws ParameterProblem {
this.repoUtil.paramterCheck(this.args, Opts.TRANSFER_OPT_STRING);
final String sourcefile = this.args.getSourcefile();
if (sourcefile == null) {
throw new ParameterProblem(Opts.TRANSFER_OPT_STRING +
" requires '" +
Opts.SOURCEFILE_OPT_STRING + "'");
}
this._checkSourcefile();
}
void parameterCheck_delete() throws ParameterProblem {
this.repoUtil.paramterCheck(this.args, Opts.DELETE_OPT_STRING);
final String name = this.args.getName();
if (name == null) {
throw new ParameterProblem("Deleting requires '" +
Opts.NAME_OPT_STRING + "' (the name " +
"of the file in your remote personal directory)");
}
}
void parameterCheck_download() throws ParameterProblem {
this.repoUtil.paramterCheck(this.args, Opts.DOWNLOAD_OPT_STRING);
final String localfile = this.args.getLocalfile();
final String name = this.args.getName();
if (localfile == null) {
throw new ParameterProblem(Opts.DOWNLOAD_OPT_STRING +
" requires '" +
Opts.LOCAL_FILE_OPT_STRING + "'");
}
if (name == null) {
throw new ParameterProblem("Downloading requires '" +
Opts.NAME_OPT_STRING + "' (the name " +
"of the file in your remote personal directory)");
}
this._checkLocalfile();
}
/* SINGLE RUN/CLUSTER RUN CHECKS: */
void parameterCheck_run() throws ParameterProblem {
final String sourcefile = this.args.getSourcefile();
final String clusterPath = this.args.getClusterPath();
final String name = this.args.getName();
final String ec2ScriptPath = this.args.getEc2ScriptPath();
// Differentiate between run and cluster-run
if (sourcefile == null && name == null && clusterPath == null) {
throw new ParameterProblem("Running requires either '" +
Opts.SOURCEFILE_OPT_STRING + "', '" +
Opts.NAME_OPT_STRING + "', or '" +
Opts.CLUSTER_OPT_STRING + "'");
}
if (sourcefile != null && name != null) {
throw new ParameterProblem("You may not specify both '" +
Opts.SOURCEFILE_OPT_STRING + "' and '" +
Opts.NAME_OPT_STRING + "'");
}
if (sourcefile == null && name == null && ec2ScriptPath != null) {
this.args.getActions().add(AllArgs.ACTION_EC2_CLUSTER);
this.print.debugln("\n*** EC2 CLUSTER HELPER\n");
this._parameterCheck_runec2cluster();
this._parameterCheck_clusterfile();
} else if (sourcefile == null && name == null) {
this.args.getActions().add(AllArgs.ACTION_RUN_CLUSTER);
this.print.debugln("\n*** RUN CLUSTER\n");
this._parameterCheck_runcommon();
this._parameterCheck_clusterfile();
} else {
this.args.getActions().add(AllArgs.ACTION_RUN_SINGLE);
this.print.debugln("\n*** RUN SINGLE\n");
this._parameterCheck_runcommon();
}
}
void _parameterCheck_clusterfile() throws ParameterProblem {
String clusterPath = this.args.getClusterPath();
this.clusterMembers = ClusterUtil.getClusterMembers(clusterPath,
this.args.getBrokerLocalNicPrefix(),
this.args.getBrokerPublicNicPrefix(),
this.print
);
// true if at least one contextualization section is present
boolean oneContextualization = false;
// true if at least one adjustment is requested
boolean adjustKnownHosts = false;
String ssh_hostsfile = this.args.getSsh_hostsfile();
if (ssh_hostsfile == null) {
this.print.errln("Your SSH known_hosts file will not be updated with " +
"generated keys (see cloud.properties to enable).");
}
for (int i = 0; i < this.clusterMembers.length; i++) {
final ClusterMember member = this.clusterMembers[i];
if (member.isOneLoginFlagPresent()) {
if (member.getClusterForUserData() == null
&& ssh_hostsfile != null) {
this.print.errln(" - Warning: Host SSH pubkey(s) will " +
"not be available for this member " +
"(it's not involved in contextualization)");
} else {
adjustKnownHosts = true;
}
}
if (member.getClusterForUserData() != null) {
oneContextualization = true;
}
}
if (this.args.isNoContextLock() && !oneContextualization) {
this.print.errln(" - Warning: You gave the --" +
Opts.NOCTXLOCK_OPT_STRING + " flag but there are no " +
"contextualization sections in the cluster definition.");
}
// at least one adjustment is requested
if (adjustKnownHosts && ssh_hostsfile != null) {
String newHostsFile = ClusterUtil.expandSshHostsFile(ssh_hostsfile,
this.print);
this.args.setSsh_hostsfile(newHostsFile);
}
}
void _parameterCheck_runcommon() throws ParameterProblem {
CloudClientUtil.checkX509Credential("Running", this.print);
this._checkServiceURL(Opts.RUN_OPT_STRING);
String sshfile = this.args.getSshfile();
if (sshfile == null) {
this.print.errln("WARNING: no SSH public key is configured");
}
if (this.args.getHistoryDirectory() == null) {
throw new ParameterProblem("Running requires '" +
Opts.HISTORY_DIR_OPT_STRING + "'");
}
this._checkHistoryDirectory("Running");
if (!this.args.isDurationMinutesConfigured()) {
throw new ParameterProblem("Running requires '" +
Opts.HOURS_OPT_STRING + "'");
}
this.print.debugln("Checking on repository URL for running " +
"because we are going to derive propagation string " +
"for the client");
this.repoUtil.paramterCheck(this.args, Opts.RUN_OPT_STRING);
final String newname = this.args.getNewname();
if (newname != null) {
this.print.debugln(
"run called with newname '" + newname + "'");
try {
this.newUnpropTargetURL =
this.repoUtil.getDerivedImageURL(newname);
} catch (Exception e) {
throw new ParameterProblem("Problem with run's newname '" +
newname + "': " + e.getMessage(), e);
}
}
if (sshfile != null) {
sshfile = CloudClientUtil.expandSshPath(sshfile);
final File f = new File(sshfile);
sshfile = f.getAbsolutePath();
this.args.setSshfile(sshfile);
this.print.debugln("Examining '" + sshfile + "'");
if (!CloudClientUtil.fileExistsAndReadable(sshfile)) {
throw new ParameterProblem("SSH public key file does not " +
"exist or is not readable: '" + sshfile + "'");
}
this.print.debugln("Exists and readable: '" + sshfile + "'");
}
if (this.args.getKernel() != null) {
final String kernel = this.args.getKernel().trim();
if (kernel.length() == 0) {
throw new ParameterProblem("empty kernel string?");
}
if (kernel.indexOf('/') >= 0) {
throw new ParameterProblem("kernel may not contain any /");
}
if (kernel.indexOf("..") >= 0) {
throw new ParameterProblem("kernel may not contain any '..'");
}
// already-propagated kernel is implied
try {
this.kernelURI = new URI("file://" + kernel);
} catch (URI.MalformedURIException e) {
throw new ParameterProblem(e.getMessage(), e);
}
}
}
void _parameterCheck_initContext() throws ParameterProblem {
CloudClientUtil.checkX509Credential("Context init helper (which talks to the " +
"context broker)", this.print);
if (this.args.getInitCtxDir() == null) {
throw new ParameterProblem("Must specify ctx output directory");
}
}
void _parameterCheck_runec2cluster() throws ParameterProblem {
CloudClientUtil.checkX509Credential("EC2 cluster helper (which talks to the " +
"context broker)", this.print);
final String brokerURL = this.args.getBrokerURL();
if (brokerURL == null) {
final String factoryHostPort = this.args.getFactoryHostPort();
if (factoryHostPort == null) {
throw new ParameterProblem(" requires either '--" +
Opts.BROKER_URL_OPT_STRING + "' or '--" +
Opts.FACTORY_OPT_STRING + "'");
}
final String url = CloudClientUtil.serviceURL(factoryHostPort);
if (!CloudClientUtil.validURL(url, this.print.getDebugProxy())) {
throw new ParameterProblem("Derived service URL is not a " +
"valid URL: '" + url + "'");
}
this.workspaceFactoryURL = url;
}
if (this.args.getHistoryDirectory() == null) {
throw new ParameterProblem("This requires '" +
Opts.HISTORY_DIR_OPT_STRING + "'");
}
this._checkHistoryDirectory("EC2 cluster helper (which talks to the " +
"context broker)");
}
/* SHARED CHECKS: */
void _checkServiceURL(String action) throws ParameterProblem {
final String factoryHostPort = this.args.getFactoryHostPort();
if (factoryHostPort == null) {
throw new ParameterProblem(action + " requires '" +
Opts.FACTORY_OPT_STRING + "'");
}
final String url = CloudClientUtil.serviceURL(factoryHostPort);
if (!CloudClientUtil.validURL(url, this.print.getDebugProxy())) {
throw new ParameterProblem("Service URL is not a valid URL: '" +
url + "'");
}
this.workspaceFactoryURL = url;
this.print.debugln("Derived workspace factory URL: '" + url + "'");
}
void _checkStatusServiceEPR(String action) throws ParameterProblem {
final String factoryHostPort = this.args.getFactoryHostPort();
if (factoryHostPort == null) {
throw new ParameterProblem(action + " requires '" +
Opts.FACTORY_OPT_STRING + "'");
}
final String url = CloudClientUtil.statusServiceURL(factoryHostPort);
if (!CloudClientUtil.validURL(url, this.print.getDebugProxy())) {
throw new ParameterProblem(
"Status Service URL is not a valid URL: '" + url + "'");
}
try {
this.statusServiceEPR =
AddressingUtils.createEndpointReference( url,
WorkspaceStatusClient.defaultResourceKey);
} catch (Exception e) {
final String err = "Problem deriving status service EPR: ";
throw new ParameterProblem(err + e.getMessage(), e);
}
this.print.debugln("Derived workspace status service URL: '" + url + "'");
}
void _checkHistoryDirectory(String action) throws ParameterProblem {
final String historyDirectory = this.args.getHistoryDirectory();
if (historyDirectory == null) {
throw new ParameterProblem(action + " requires '" +
Opts.HISTORY_DIR_OPT_STRING + "'");
}
CloudClientUtil.verifyHistoryDir(historyDirectory, true, true);
}
void _translateHandle(String action) throws ParameterProblem {
if (this.args.getHandle() == null) {
this.print.debugln("no handle supplied");
return;
}
if (this.args.getHistorySubDir() != null) {
this.print.debugln("handle supplied, but presence of history " +
"sub-directory argument overrides it");
return;
}
if (this.args.getHistoryDirectory() == null) {
throw new ParameterProblem("Not able to use handle to locate the " +
"necessary, stored information: no top-level history " +
"directory argument was supplied.");
}
this._checkHistoryDirectory(action);
// translate history directory and handle argument into history subdir,
// the result will be checked later by whatever needs it
final String historySubDir = this.args.getHistoryDirectory() +
File.separator + this.args.getHandle();
this.args.setHistorySubDir(historySubDir);
}
void _checkSpecificEPR(String action)
throws ParameterProblem {
final String historySubDir = this.args.getHistorySubDir();
final String eprGivenFilePath = this.args.getEprGivenFilePath();
if (historySubDir == null && eprGivenFilePath == null) {
// This is a message present to human. An unmentioned, third option
// is technically possible. It's more esoteric, but one could
// specify Opts.HISTORY_SUBDIR_OPT_STRING directly.
throw new ParameterProblem(action + " requires either " +
"'" + Opts.HANDLE_OPT_STRING +
"' or path to specific EPR file using '" +
Opts.EPR_FILE_OPT_STRING + "'");
}
if (historySubDir != null && eprGivenFilePath != null) {
throw new ParameterProblem(action + " will use either '" +
Opts.HISTORY_SUBDIR_OPT_STRING +
"' or '" + Opts.EPR_FILE_OPT_STRING +
"', but you've provided BOTH options.");
}
File f;
if (historySubDir != null) {
CloudClientUtil.verifyHistoryDir(historySubDir, false, false);
f = new File(historySubDir, HistoryUtil.SINGLE_EPR_FILE_NAME);
if (!CloudClientUtil.fileExistsAndReadable(f)) {
f = new File(historySubDir, HistoryUtil.ENSEMBLE_EPR_FILE_NAME);
if (CloudClientUtil.fileExistsAndReadable(f)) {
this.isClusterHandle = true;
} else {
throw new ParameterProblem("Cannot find or read any " +
"instance or cluster EPRs under '" +
historySubDir + "'\nPerhaps this launch did " +
"not succeed?");
}
}
} else {
f = new File(eprGivenFilePath);
if (!CloudClientUtil.fileExistsAndReadable(f)) {
throw new ParameterProblem("Cannot find or read '" +
eprGivenFilePath + "'");
}
}
String old = null;
if (this.specificEPRpath != null) {
old = this.specificEPRpath;
}
this.specificEPRpath = f.getAbsolutePath();
if (old != null) {
if (!old.equals(this.specificEPRpath)) {
throw new ParameterProblem(
"Unexpected with any input: specific EPR that was " +
"previously set is '" + old + "' but it is " +
"not the same as a repeat derivation which " +
"is '" + this.specificEPRpath + "'. Please " +
"send debug output file (in the history " +
"directory) to developers, thankyou.");
}
}
}
void _checkSpecificBrokerEPR(String action)
throws ParameterProblem {
final String historySubDir = this.args.getHistorySubDir();
final String eprGivenFilePath = this.args.getEprGivenFilePath();
if (historySubDir == null && eprGivenFilePath == null) {
// This is a message present to human. An unmentioned, third option
// is technically possible. It's more esoteric, but one could
// specify Opts.HISTORY_SUBDIR_OPT_STRING directly.
throw new ParameterProblem(action + " requires either " +
"'" + Opts.HANDLE_OPT_STRING +
"' or path to specific EPR file using '" +
Opts.EPR_FILE_OPT_STRING + "'");
}
if (historySubDir != null && eprGivenFilePath != null) {
throw new ParameterProblem(action + " will use either '" +
Opts.HISTORY_SUBDIR_OPT_STRING +
"' or '" + Opts.EPR_FILE_OPT_STRING +
"', but you've provided BOTH options.");
}
File f;
if (historySubDir != null) {
CloudClientUtil.verifyHistoryDir(historySubDir, false, false);
f = new File(historySubDir, HistoryUtil.CONTEXT_EPR_FILE_NAME);
if (!CloudClientUtil.fileExistsAndReadable(f)) {
throw new ParameterProblem("Cannot find or read any " +
"context EPRs under '" +
historySubDir + "'\nPerhaps this launch did " +
"not succeed or it was not a virtual cluster launch " +
"using the context broker?");
}
} else {
f = new File(eprGivenFilePath);
if (!CloudClientUtil.fileExistsAndReadable(f)) {
throw new ParameterProblem("Cannot find or read '" +
eprGivenFilePath + "'");
}
}
String old = null;
if (this.specificEPRpath != null) {
old = this.specificEPRpath;
}
this.specificEPRpath = f.getAbsolutePath();
if (old != null) {
if (!old.equals(this.specificEPRpath)) {
throw new ParameterProblem(
"Unexpected with any input: specific EPR that was " +
"previously set is '" + old + "' but it is " +
"not the same as a repeat derivation which " +
"is '" + this.specificEPRpath + "'. Please " +
"send debug output file (in the history " +
"directory) to developers, thankyou.");
}
}
}
void _checkSourcefile() throws ParameterProblem {
final String sourcefile = this.args.getSourcefile();
if (!CloudClientUtil.fileExistsAndReadable(sourcefile)) {
throw new ParameterProblem("Specified source file does not " +
"exist or is not readable: '" + sourcefile + "'");
}
}
void _checkLocalfile() throws ParameterProblem {
final String localfile = this.args.getLocalfile();
if (CloudClientUtil.fileExists(localfile)) {
throw new ParameterProblem("Specified local target file already " +
"exists: '" + localfile + "'");
}
}
void _checkDepReqDefaults(String action) throws ParameterProblem {
this.__checknull(action, "deployment request file name",
this.args.getDeploymentRequest_fileName());
}
void _checkMetadataDefaults(String action) throws ParameterProblem {
this.__checknull(action, "association name", this.args.getMetadata_association());
this.__checknull(action, "cpu type", this.args.getMetadata_cpuType());
this.__checknull(action, "metadata filename", this.args.getMetadata_fileName());
this.__checknull(action, "partition mount-as", this.args.getMetadata_mountAs());
this.__checknull(action, "NIC name", this.args.getMetadata_nicName());
this.__checknull(action, "VMM type", this.args.getMetadata_vmmType());
this.__checknull(action, "VMM version", this.args.getMetadata_vmmVersion());
}
void __checknull(String action,
String propname,
String val) throws ParameterProblem {
if (val == null) {
throw new ParameterProblem(action + " requires " + propname);
}
}
/* DERIVED FIELDS */
// only used for printing and/or presence-detect
GlobusCredential loadX509BeingUsed() throws Exception {
if (this.x509Used != null) {
return this.x509Used;
}
this.x509Used = CloudClientUtil.getActiveX509Credential(this.print);
return this.x509Used;
}
// -------------------------------------------------------------------------
// EXECUTE
// -------------------------------------------------------------------------
void runNoParameterCheck() throws ExecutionProblem, ExitNow {
if (this.action_help()) {
return; // if a help action ran, cut out early
}
this.action_hashPrint();
this.trustedCAs();
this.action_justPrinting();
this.action_assoc_query();
this.action_list();
this.action_status();
this.action_save();
this.action_destroy();
this.action_transfer();
this.action_run_single();
this.action_run_cluster();
this.action_run_ec2cluster();
this.action_init_context();
this.action_download();
this.action_delete();
this.action_print_context_status();
}
void trustedCAs() throws ExecutionProblem {
final String sectionTitle = "TRUSTED CAs CHECK";
CommonPrint.printDebugSection(this.print, sectionTitle);
final String caAppendDir = this.args.getCaAppendDir();
try {
if (caAppendDir != null) {
this.print.debugln("caAppendDir = '" + caAppendDir + "'");
TrustedCAs.addTrustedCaDirectory(caAppendDir);
this.print.debugln("Added '" + caAppendDir + "' to " +
"trusted certificate directories");
} else {
this.print.debugln("caAppendDir not present");
}
this.trustedCertDirs =
CertUtil.trustedCertificateDirectories(
this.print.getDebugProxy());
} catch (Exception e) {
throw new ExecutionProblem(e.getMessage(), e); // ...
}
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
// returns true if a help action ran
boolean action_help() throws ExecutionProblem {
try {
if (this.args.getActions().contains(AllArgs.ACTION_USAGE)) {
this.print.infoln(new Help().getUsageString());
return true;
}
if (this.args.getActions().contains(AllArgs.ACTION_HELP)) {
this.print.infoln(new Help().getHelpString());
return true;
}
if (this.args.getActions().contains(AllArgs.ACTION_EXTRAHELP)) {
this.print.infoln(new Help().getExtraHelpString());
return true;
}
} catch (IOException e) {
throw new ExecutionProblem("Unexpected problem with help system: "
+ e.getMessage(), e);
}
return false;
}
void action_hashPrint() throws ExecutionProblem {
if (this.args.getActions().contains(AllArgs.ACTION_HASH_PRINT)) {
//this.print.infoln(" DN: " + this.hashPrintDN);
try {
//this.print.infoln("HASH: " +
// SecurityUtil.hashDN(this.hashPrintDN));
this.print.infoln(SecurityUtil.hashDN(this.args.getHashPrintDN()));
} catch (NoSuchAlgorithmException e) {
throw new ExecutionProblem(e.getMessage(), e);
}
}
}
void action_justPrinting() throws ExecutionProblem {
try {
if (this.args.getActions().contains(AllArgs.ACTION_SECURITY_PRINT)) {
final String sectionTitle = "ACTION: SECURITY PRINT";
CommonPrint.printDebugSection(this.print, sectionTitle);
final SecurityPrinter sp =
new SecurityPrinter(this.x509Used,
this.trustedCertDirs);
sp.print(this.args.getCaHash(),
this.print.getInfoProxy(),
this.print.getDebugProxy());
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (this.args.getActions().contains(AllArgs.ACTION_SERVICE_PRINT)) {
final String sectionTitle = "ACTION: SERVICE PRINT";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.print.infoln(this.workspaceFactoryURL);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
if (this.args.getActions().contains(AllArgs.ACTION_TARGET_PRINT)) {
final String sectionTitle = "ACTION: TARGET URL PRINT";
CommonPrint.printDebugSection(this.print, sectionTitle);
String sourcefile = this.args.getSourcefile();
String name = this.args.getName();
if (sourcefile != null) {
final File f = new File(sourcefile);
name = f.getName();
}
if(name != null) {
String pUrl = this.repoUtil.getRemoteUrl(name);
this.print.infoln(pUrl);
} else {
throw new ExecutionProblem(
"print target configured but no target URL?");
}
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
} catch (Exception e) {
throw new ExecutionProblem(e.getMessage(), e); // ...
}
}
void action_list() throws ExecutionProblem {
if (this.args.getActions().contains(AllArgs.ACTION_LIST)) {
final String sectionTitle = "ACTION: LIST";
CommonPrint.printDebugSection(this.print, sectionTitle);
final FileListing[] files =
this.repoUtil.listFiles(
this.print.getInfoProxy(),
this.print.getErrProxy(),
this.print.getDebugProxy());
CloudClientUtil.printFileList(files, this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void action_destroy() throws ExecutionProblem, ExitNow {
if (this.args.getActions().contains(AllArgs.ACTION_DESTROY)) {
final String sectionTitle = "ACTION: DESTROY";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.executeUtil.destroy(this.specificEPRpath,
this.args.getFactoryID(),
this.isClusterHandle,
this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void action_status() throws ExecutionProblem, ExitNow {
if (this.args.getActions().contains(AllArgs.ACTION_STATUS_CHECK)) {
if (this.specificEPRpath == null) {
this._action_status_all();
} else {
this._action_status_one();
}
}
}
private void _action_status_one() throws ExecutionProblem, ExitNow {
final String sectionTitle = "ACTION: STATUS CHECK (one workspace)";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.executeUtil.statusQuery(this.specificEPRpath,
this.args.getFactoryID(),
this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
private void _action_status_all() throws ExecutionProblem, ExitNow {
final String sectionTitle = "ACTION: STATUS CHECK (all workspaces)";
CommonPrint.printDebugSection(this.print, sectionTitle);
final StubConf conf = new StubConf();
conf.setEPR(this.statusServiceEPR);
if (this.args.getFactoryID() != null) {
conf.setAuthorization(
new IdentityAuthorization(this.args.getFactoryID()));
} else {
conf.setAuthorization(HostAuthorization.getInstance());
}
final Status_QueryAll queryAll =
new Status_QueryAll(this.statusServiceEPR, conf, this.print);
this.print.infoln("Querying for ALL instances.\n");
try {
final Workspace[] workspaces = queryAll.queryAll();
CloudClientUtil.printCurrent(workspaces,
this.print,
this.args.getHistoryDirectory(),
this.statusServiceEPR);
} catch (WorkspaceStatusFault e) {
throw new ExecutionProblem(e.getMessage(), e);
} catch (ParameterProblem e) {
throw new ExecutionProblem(e.getMessage(), e);
}
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
void action_save() throws ExecutionProblem, ExitNow {
if (this.args.getActions().contains(AllArgs.ACTION_SAVE)) {
final String sectionTitle = "ACTION: SAVE";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.executeUtil.save(this.args.getNewname(),
this.newUnpropTargetURL,
this.specificEPRpath,
this.args.getPollMs(),
this.args.isUseNotifications(),
this.args.getFactoryID(),
this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void action_transfer() throws ExecutionProblem {
if (this.args.getActions().contains(AllArgs.ACTION_TRANSFER)) {
final String sectionTitle = "ACTION: TRANSFER";
CommonPrint.printDebugSection(this.print, sectionTitle);
final String sourcefile = this.args.getSourcefile();
final File f = new File(sourcefile);
this.repoUtil.uploadVM(
sourcefile,
f.getName(),
this.print.getInfoProxy(),
this.print.getDebugProxy(),
this.executeUtil.getExecer());
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void action_assoc_query() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_ASSOC_QUERY)) {
return; // *** EARLY RETURN ***
}
final String sectionTitle = "ACTION: NETWORK QUERY";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.executeUtil.associationQuery(this.workspaceFactoryURL,
this.args.getFactoryID(),
this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
void action_run_single() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_RUN_SINGLE)) {
return; // *** EARLY RETURN ***
}
final String sectionTitle = "ACTION: RUN SINGLE";
CommonPrint.printDebugSection(this.print, sectionTitle);
String imageName = this.args.getName();
if (imageName == null) {
final File sfile = new File(this.args.getSourcefile());
imageName = sfile.getName();
this.print.debugln("Derived image name to run from " +
"given sourcefile: '" + imageName + "'");
} else {
this.print.debugln("Using given image name: '" + imageName + "'");
}
final String imageURL;
try {
imageURL = this.repoUtil.getDerivedImageURL(imageName);
} catch (Exception e) {
throw new ExecutionProblem("Problem with image name '" +
imageName + "': " + e.getMessage(), e);
}
final URI imageURI;
try {
imageURI = new URI(imageURL);
} catch (URI.MalformedURIException e) {
throw new ExecutionProblem(e.getMessage(), e);
}
final String[] associations = {this.args.getMetadata_association()};
final String[] nicnames = {this.args.getMetadata_nicName()};
// runName (3rd method paramater, being set to null) will be set in
// startOneWorkspace once rundir is known
final VirtualWorkspace_Type metadata =
MetadataXMLUtil.constructMetadata(imageURI,
this.args.getMetadata_mountAs(),
null,
associations,
nicnames,
this.args.getMetadata_cpuType(),
this.args.getMetadata_vmmVersion(),
this.args.getMetadata_vmmType(),
this.kernelURI);
final WorkspaceDeployment_Type deploymentRequest =
DeploymentXMLUtil.constructDeployment(this.args.getDurationMinutes(),
this.args.getMemory(),
this.args.getCores(),
this.newUnpropTargetURL);
this.executeUtil.startOneWorkspace(this.workspaceFactoryURL,
metadata,
this.args.getMetadata_fileName(),
deploymentRequest,
this.args.getDeploymentRequest_fileName(),
this.args.getSshfile(),
this.args.getHistoryDirectory(),
this.args.getPollMs(),
this.args.isUseNotifications(),
this.args.getFactoryID(),
this.print);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
void action_run_cluster() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_RUN_CLUSTER)) {
return; // *** EARLY RETURN ***
}
final String sectionTitle = "ACTION: RUN CLUSTER";
CommonPrint.printDebugSection(this.print, sectionTitle);
final int len = this.clusterMembers.length;
final VirtualWorkspace_Type[] metadatas =
new VirtualWorkspace_Type[len];
final WorkspaceDeployment_Type[] deploymentRequests =
new WorkspaceDeployment_Type[len];
final String[] metadata_fileNames = new String[len];
final String[] deploymentRequest_fileNames = new String[len];
for (int i = 0; i < len; i++) {
final ClusterMember member = this.clusterMembers[i];
if (member == null) {
throw new IllegalStateException(
"valid clusterMembers must be present here");
}
final String imageName = member.getImageName();
final String imageURL;
try {
imageURL = this.repoUtil.getDerivedImageURL(imageName);
} catch (Exception e) {
throw new ExecutionProblem("Problem with image name '" +
imageName + "': " + e.getMessage(), e);
}
final URI imageURI;
try {
imageURI = new URI(imageURL);
} catch (URI.MalformedURIException e) {
throw new ExecutionProblem(e.getMessage(), e);
}
// runName (3rd method paramater, being set to null) will be set
// in startWorkspaceCluster once rundir is known
metadatas[i] =
MetadataXMLUtil.constructMetadata(imageURI,
this.args.getMetadata_mountAs(),
null,
member.getAssociations(),
member.getIfaceNames(),
this.args.getMetadata_cpuType(),
this.args.getMetadata_vmmVersion(),
this.args.getMetadata_vmmType(),
this.kernelURI);
deploymentRequests[i] =
DeploymentXMLUtil.constructDeployment(this.args.getDurationMinutes(),
this.args.getMemory(),
this.args.getCores(),
this.newUnpropTargetURL,
member.getQuantity());
metadata_fileNames[i] =
HistoryUtil.getMemberName(i+1) + "-" +
this.args.getMetadata_fileName();
deploymentRequest_fileNames[i] =
HistoryUtil.getMemberName(i+1) + "-" +
this.args.getDeploymentRequest_fileName();
}
ClusterUtil.printClusterInfo(this.clusterMembers, this.print);
final String[] printNames = new String[this.clusterMembers.length];
final Cloudcluster_Type[] clustersForUserData =
new Cloudcluster_Type[this.clusterMembers.length];
for (int i = 0; i < this.clusterMembers.length; i++) {
final int memberIndex = i;
final ClusterMember member = this.clusterMembers[memberIndex];
printNames[i] = member.getPrintName(); // may be null
// will be null if not involved in contextualization
clustersForUserData[memberIndex] = member.getClusterForUserData();
printNames[i] = member.getPrintName(); // may be null
}
final KnownHostsTask[] knownHostTasks;
if (this.args.getSsh_hostsfile() != null) {
knownHostTasks =
ClusterUtil.constructKnownHostTasks(this.clusterMembers,
this.args.isHostkeyDir());
} else {
knownHostTasks = null;
}
this.executeUtil.startWorkspaceCluster(this.workspaceFactoryURL,
knownHostTasks,
metadatas,
metadata_fileNames,
deploymentRequests,
deploymentRequest_fileNames,
printNames,
clustersForUserData,
!this.args.isNoContextLock(),
this.args.getSshfile(),
this.args.getSsh_hostsfile(),
this.args.getHistoryDirectory(),
this.args.getPollMs(),
this.args.getFactoryID(),
this.print,
this.args.getBrokerURL(),
this.args.getBrokerID());
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
class CtxMemberInfo {
private final String image;
private final int quantity;
private final ClusterMember clusterMember;
public CtxMemberInfo(ClusterMember member) throws ExecutionProblem {
if (member == null) {
throw new IllegalArgumentException("member may not be null");
}
this.clusterMember = member;
this.image = member.getImageName();
if (this.image == null ||
this.image.trim().length() == 0) {
throw new ExecutionProblem("image name missing from " +
"cluster document");
}
this.quantity = member.getQuantity();
}
}
void validateClusterMembersForCtxClient() throws ExecutionProblem {
if (this.clusterMembers == null) {
throw new ExecutionProblem("no clusterMembers provided");
}
for (ClusterMember member : this.clusterMembers) {
if (member == null) {
throw new IllegalStateException(
"valid clusterMembers must be present here");
}
final String imageName = member.getImageName();
if (imageName == null || imageName.trim().length() == 0) {
throw new ExecutionProblem("No AMI in cluster file");
}
}
}
void action_init_context() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_INIT_CONTEXT)) {
return; // *** EARLY RETURN ***
}
String brokerURL = this.args.getBrokerURL();
String brokerIdentityAuthorization = this.args.getBrokerID();
if (brokerURL == null) {
int dx = this.workspaceFactoryURL.indexOf("WorkspaceFactoryService");
brokerURL = this.workspaceFactoryURL.substring(0,dx);
brokerURL += "NimbusContextBroker";
print.debugln("No context broker URL was explicitly supplied," +
" so it has been deduced from the nimbus factory URL." +
" Using: " + brokerURL);
// and so ID scheme for service must be copied
if (brokerIdentityAuthorization == null
&& this.args.getFactoryID() != null) {
brokerIdentityAuthorization = this.args.getFactoryID();
}
}
this.validateClusterMembersForCtxClient();
this.executeUtil.ctxClusterHelp(this.clusterMembers,
brokerURL, brokerIdentityAuthorization,
!this.args.isNoContextLock(),
this.args.getInitCtxDir(),
this.print);
}
void action_print_context_status() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_PRINT_CTX_STATUS)) {
return; // *** EARLY RETURN ***
}
String brokerIdentityAuthorization = this.args.getBrokerID();
if (brokerIdentityAuthorization == null
&& this.args.getFactoryID() != null) {
brokerIdentityAuthorization = this.args.getFactoryID();
}
this.executeUtil.printContextStatusQuery(this.specificEPRpath,
brokerIdentityAuthorization,
this.print);
}
void action_run_ec2cluster() throws ExecutionProblem, ExitNow {
if (!this.args.getActions().contains(AllArgs.ACTION_EC2_CLUSTER)) {
return; // *** EARLY RETURN ***
}
this.validateClusterMembersForCtxClient();
final String sectionTitle = "ACTION: EC2 CLUSTER HELP";
CommonPrint.printDebugSection(this.print, sectionTitle);
print.infoln("\nEC2 cluster:");
for (int i = 0; i < this.clusterMembers.length; i++) {
final ClusterMember member = this.clusterMembers[i];
String inststr = " instance";
if (member.getQuantity() > 1) {
inststr += "s";
}
final String mname;
if (member.getPrintName() == null) {
mname = HistoryUtil.getMemberName(i+1);
} else {
mname = member.getPrintName();
}
this.print.infoln(" - " + mname + ": AMI '" +
member.getImageName() + "', " + member.getQuantity() +
inststr);
}
String brokerURL = this.args.getBrokerURL();
String brokerIdentityAuthorization = this.args.getBrokerID();
if (brokerURL == null) {
int dx = this.workspaceFactoryURL.indexOf("WorkspaceFactoryService");
brokerURL = this.workspaceFactoryURL.substring(0,dx);
brokerURL += "NimbusContextBroker";
print.debugln("No context broker URL was explicitly supplied," +
" so it has been deduced from the nimbus factory URL." +
" Using: " + brokerURL);
// and so ID scheme for service must be copied
if (brokerIdentityAuthorization == null
&& this.args.getFactoryID() != null) {
brokerIdentityAuthorization = this.args.getFactoryID();
}
}
this.executeUtil.ec2ClusterHelp(this.clusterMembers,
brokerURL, brokerIdentityAuthorization,
!this.args.isNoContextLock(),
this.args.getPollMs(),
this.args.getEc2ScriptPath(),
this.args.getHistoryDirectory(),
this.print
);
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
void action_download() throws ExecutionProblem {
if (this.args.getActions().contains(AllArgs.ACTION_DOWNLOAD)) {
final String sectionTitle = "ACTION: DOWNLOAD";
CommonPrint.printDebugSection(this.print, sectionTitle);
final String localfile = this.args.getLocalfile();
final String name = this.args.getName();
this.repoUtil.downloadVM(
localfile,
name,
this.print.getInfoProxy(),
this.print.getDebugProxy(),
this.executeUtil.getExecer());
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
void action_delete() throws ExecutionProblem {
if (this.args.getActions().contains(AllArgs.ACTION_DELETE)) {
final String sectionTitle = "ACTION: DELETE";
CommonPrint.printDebugSection(this.print, sectionTitle);
this.repoUtil.deleteVM(
this.args.getName(),
this.print.getInfoProxy(),
this.print.getDebugProxy());
CommonPrint.printDebugSectionEnd(this.print, sectionTitle);
}
}
}