ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject svn commit: r1348558 - in /ace/trunk: ace-nodelauncher-amazon/ ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/ ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/ ace-nodelauncher-api/src/main/java/org/ap...
Date Sun, 10 Jun 2012 09:56:35 GMT
Author: paulb
Date: Sun Jun 10 09:56:35 2012
New Revision: 1348558

URL: http://svn.apache.org/viewvc?rev=1348558&view=rev
Log:
ACE-277 Cloud nodes can now be configured from the UI.

Added:
    ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
    ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncherConfig.java
Modified:
    ace/trunk/ace-nodelauncher-amazon/pom.xml
    ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
    ace/trunk/ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/PortParseTest.java
    ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncher.java
    ace/trunk/ace-nodelauncher-ui/pom.xml
    ace/trunk/ace-nodelauncher-ui/src/main/java/org/apache/ace/nodelauncher/ui/NodePanel.java

Modified: ace/trunk/ace-nodelauncher-amazon/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-amazon/pom.xml?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-amazon/pom.xml (original)
+++ ace/trunk/ace-nodelauncher-amazon/pom.xml Sun Jun 10 09:56:35 2012
@@ -67,6 +67,10 @@
         </bundle.activator>
         <embed.dependency>*;scope=compile;groupId=!org.osgi|org.apache.felix|org.apache.ace</embed.dependency>
         <embed.transitive>true</embed.transitive>
+        <export.package>
+            org.apache.ace.nodelauncher.amazon;version=${project.version},
+            org.jclouds.compute.domain
+        </export.package>
     </properties>
 
     <dependencies>

Modified: ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
(original)
+++ ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/AmazonNodeLauncher.java
Sun Jun 10 09:56:35 2012
@@ -18,23 +18,20 @@
  */
 package org.apache.ace.nodelauncher.amazon;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.io.Files;
-import com.google.inject.Module;
 import org.apache.ace.nodelauncher.NodeLauncher;
+import org.apache.ace.nodelauncher.NodeLauncherConfig;
 import org.jclouds.compute.ComputeService;
-import org.jclouds.compute.ComputeServiceContext;
-import org.jclouds.compute.ComputeServiceContextFactory;
 import org.jclouds.compute.domain.ComputeMetadata;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.NodeState;
-import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
 import org.jclouds.compute.options.RunScriptOptions;
-import org.jclouds.domain.Credentials;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.LoginCredentials;
 import org.jclouds.ec2.compute.options.EC2TemplateOptions;
 import org.jclouds.ec2.domain.InstanceType;
 import org.jclouds.scriptbuilder.domain.Statements;
-import org.jclouds.sshj.config.SshjSshClientModule;
 import org.osgi.service.cm.ConfigurationException;
 import org.osgi.service.cm.ManagedService;
 
@@ -42,10 +39,11 @@ import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.charset.Charset;
-import java.util.*;
+import java.util.Dictionary;
+import java.util.Properties;
+import java.util.Set;
 
 import static org.jclouds.compute.predicates.NodePredicates.runningInGroup;
-
 /**
  * Simple NodeLauncher implementation that launches nodes based on a given AMI in Amazon
EC2.
  * We expect the AMI we launch to have a java on its path, at least after bootstrap.<br><br>
@@ -71,6 +69,11 @@ public class AmazonNodeLauncher implemen
     public static final String AMI_ID = "amiId";
 
     /**
+     * Configuration key: The ID of the AMI owner to use. You need this when you want to
use your own AMIs.
+     */
+    public static final String AMI_OWNER_ID = "amiOwnerId";
+
+    /**
      * Configuration key: The location where the node should be started; this is an Amazon
"availability zone",
      * something like "eu-west-1".
      */
@@ -134,7 +137,7 @@ public class AmazonNodeLauncher implemen
     /**
      * Default set of ports to open on a node.
      */
-    public static final int[] DEFAULT_PORTS = new int[] {22, 80, 8080};
+    public static final int[] DEFAULT_PORTS = new int[]{22, 80, 8080};
 
     /**
      * Configuration key: The (optional) name of the JAR to launch to
@@ -154,69 +157,88 @@ public class AmazonNodeLauncher implemen
      * bootstrapping.
      */
     public static final String EXTERNAL_DOWNLOAD_URLS = "externalDownloadUrls";
-    
+
+    /**
+     * Configuration key: The (optional) ssh user to use when connecting to the node. Uses
jclouds defaults by default,
+     * which is root and ec2-user.
+     */
+    public static final String SSH_USER = "sshUser";
+
     /**
      * Configuration key: The (optional) private key file, which you must install on
      * the ACE server locally if you want it to be used when creating new nodes.
      */
     private static final String PRIVATE_KEY_FILE = "privateKeyFile";
 
-    private URL m_server;
-    private String m_amiId;
-    private String m_location;
-    private String m_hardwareId;
-    private String m_accessKeyId;
-    private String m_secretAccessKey;
-    private String m_keypair;
-    private String m_privateKeyFile;
-    private String m_tagPrefix;
-    private String m_vmOptions;
-    private String m_nodeBootstrap;
-    private String m_launcherArguments;
-    private String m_extraPorts;
-    private boolean m_runAsRoot;
-    private String m_aceLauncher;
-    private String m_additionalObrDownloads;
-    private String m_externalDownloadUrls;
-
-
-    private ComputeServiceContext m_computeServiceContext;
-
-    public void start() {
-        Properties props = new Properties();
-        m_computeServiceContext = new ComputeServiceContextFactory().createContext("aws-ec2",
m_accessKeyId, m_secretAccessKey, ImmutableSet.<Module> of(new SshjSshClientModule()),
props);
-    }
+    /**
+     * Default configuration object. Properties are read from the nodelauncher configuration
file.
+     */
+    private JcloudsNodeLauncherConfig m_defaultNodeConfig;
+
+    /**
+     * Current configuration object. This reflects settings done from the UI for example.
+     * This instance is set when a node is started.
+     */
+    private JcloudsNodeLauncherConfig m_currentConfig;
+
 
     public void start(String id) throws Exception {
-        ComputeService computeService = m_computeServiceContext.getComputeService();
-        Template template = computeService.templateBuilder()
-            .imageId(m_location + "/" + m_amiId)
-            .hardwareId(m_hardwareId)
-            .locationId(m_location)
-            .build();
 
-        int[] extraPorts = parseExtraPorts(m_extraPorts);
+        start(id, m_defaultNodeConfig);
+    }
+
+    public void start(String id, NodeLauncherConfig cfg) throws Exception {
+        JcloudsNodeLauncherConfig config = (JcloudsNodeLauncherConfig) cfg;
+        m_currentConfig = config;
+
+        ComputeService computeService = config.getComputeService();
+        TemplateBuilder template = computeService.templateBuilder()
+                .imageId(config.getImageId())
+                .hardwareId(config.getHardwareId())
+                .locationId(config.getLocation());
+
+        int[] extraPorts = parseExtraPorts(config.getExtraPorts());
         int[] inboundPorts = mergePorts(DEFAULT_PORTS, extraPorts);
-        template.getOptions().as(EC2TemplateOptions.class).inboundPorts(inboundPorts);
-        template.getOptions().blockOnComplete(false);
-        template.getOptions().runAsRoot(m_runAsRoot);
 
-        if (useConfiguredKeyPair()) {
-            template.getOptions().as(EC2TemplateOptions.class).keyPair(m_keypair);
-            template.getOptions().overrideCredentialsWith(new Credentials("ec2-user", Files.toString(new
File(m_privateKeyFile), Charset.defaultCharset())));
+        TemplateOptions options = new EC2TemplateOptions()
+                .as(EC2TemplateOptions.class).inboundPorts(inboundPorts)
+                .blockOnComplete(false)
+                .runAsRoot(config.isRunAsRoot());
+
+        if (useConfiguredKeyPair(config)) {
+            options.as(EC2TemplateOptions.class).keyPair(config.getKeyPair());
         }
 
-        Set<? extends NodeMetadata> tag = computeService.createNodesInGroup(m_tagPrefix
+ id, 1, template);
-        if (!useConfiguredKeyPair()) {
+        template.options(options);
+
+        Set<? extends NodeMetadata> tag = computeService.createNodesInGroup(config.getTagPrefix()
+ id, 1, template.build());
+        if (!useConfiguredPrivateKey(config)) {
             System.out.println("In case you need it, this is the key to ssh to " + id + ":\n"
+ tag.iterator().next().getCredentials().credential);
         }
-        computeService.runScriptOnNodesMatching(runningInGroup(m_tagPrefix + id),
-            Statements.exec(buildStartupScript(id)),
-            RunScriptOptions.Builder.blockOnComplete(false));
+
+        LoginCredentials.Builder loginBuilder = LoginCredentials.builder();
+
+        if (config.getSshUser() != null && config.getSshUser().length() > 0) {
+            loginBuilder.user(config.getSshUser());
+        } else {
+            loginBuilder.user("ec2-user");
+        }
+
+        if (useConfiguredPrivateKey(config)) {
+            loginBuilder.privateKey(Files.toString(new File(config.getPrivateKeyFile()),
Charset.defaultCharset()));
+        }
+
+        computeService.runScriptOnNodesMatching(runningInGroup(config.getTagPrefix() + id),
+                Statements.exec(buildStartupScript(id, config)),
+                RunScriptOptions.Builder.blockOnComplete(false).overrideLoginCredentials(loginBuilder.build()));
     }
 
-    private boolean useConfiguredKeyPair() {
-        return m_keypair != null && m_keypair.length() > 0;
+    private boolean useConfiguredPrivateKey(JcloudsNodeLauncherConfig config) {
+        return config.getPrivateKeyFile() != null && config.getPrivateKeyFile().length()
> 0;
+    }
+
+    private boolean useConfiguredKeyPair(JcloudsNodeLauncherConfig config) {
+        return config.getKeyPair() != null && config.getKeyPair().length() > 0;
     }
 
     int[] mergePorts(int[] first, int[] last) {
@@ -227,53 +249,56 @@ public class AmazonNodeLauncher implemen
         return result;
     }
 
-    int[] parseExtraPorts(String extraPorts) {
-        extraPorts = extraPorts.trim();
-        if (extraPorts.isEmpty()) {
-            return new int[]{};
-        }
-        String[] ports = extraPorts.split(",");
-        int[] result = new int[ports.length];
-        for (int i = 0; i < ports.length; i++) {
-            result[i] = Integer.parseInt(ports[i].trim());
+    int[] parseExtraPorts(String[] extraPorts) {
+        if(extraPorts == null || extraPorts.length == 0) {
+            return new int[0];
+        }
+
+        int[] result = new int[extraPorts.length];
+
+        for (int i = 0; i < extraPorts.length; i++) {
+            result[i] = Integer.parseInt(extraPorts[i].trim());
         }
+
         return result;
     }
 
-    private String buildStartupScript(String id) throws MalformedURLException {
-        StringBuilder script = new StringBuilder();
-        if (m_nodeBootstrap != null && m_nodeBootstrap.length() > 0) {
-            script.append(m_nodeBootstrap).append(" ; ");
+    private String buildStartupScript(String id, JcloudsNodeLauncherConfig config) throws
MalformedURLException {
+        StringBuilder script = new StringBuilder("cd ~; ");
+        if (config.getNodeBootstrap() != null && config.getNodeBootstrap().length()
> 0) {
+            script.append(config.getNodeBootstrap()).append(" ; ");
         }
 
-        script.append("wget ").append(new URL(m_server, "/obr/" + m_aceLauncher)).append("
;");
-        if (m_additionalObrDownloads.length() > 0) {
-            for (String additonalDownload : m_additionalObrDownloads.split(",")) {
-                script.append("wget ").append(new URL(m_server, "/obr/" + additonalDownload.trim())).append("
;");
+        script.append("wget ").append(new URL(config.getServer(), "/obr/" + config.getAceLauncher())).append("
;");
+        if (config.getAdditionalObrDownloads().length() > 0) {
+            for (String additonalDownload : config.getAdditionalObrDownloads().split(","))
{
+                script.append("wget ").append(new URL(config.getServer(), "/obr/" + additonalDownload.trim())).append("
;");
             }
         }
 
-        if (m_externalDownloadUrls.length() > 0) {
-            for (String additonalDownload : m_externalDownloadUrls.split(",")) {
+        if (config.getExternalDownloadUrls().length() > 0) {
+            for (String additonalDownload : config.getExternalDownloadUrls().split(","))
{
                 script.append("wget ").append(additonalDownload.trim()).append(" ;");
             }
         }
-        script.append("nohup java -jar ").append(m_aceLauncher).append(" ");
-        script.append("discovery=").append(m_server.toExternalForm()).append(" ");
+        script.append("nohup java -jar ").append(config.getAceLauncher()).append(" ");
+        script.append("discovery=").append(config.getServer().toExternalForm()).append("
");
         script.append("identification=").append(id).append(" ");
-        script.append(m_vmOptions).append(" ");
-        script.append(m_launcherArguments);
+        script.append(config.getVmOptions()).append(" ");
+        script.append(config.getLauncherArguments());
         return script.toString();
     }
 
     public void stop(String id) {
-        m_computeServiceContext.getComputeService().destroyNodesMatching(runningInGroup(m_tagPrefix
+ id));
+
+        getActiveConfig().getComputeService().destroyNodesMatching(runningInGroup(getActiveConfig().getTagPrefix()
+ id));
     }
 
     public Properties getProperties(String id) throws Exception {
         Properties result = new Properties();
 
-        NodeMetadata nodeMetadata = getNodeMetadataForRunningNodeWithTag(m_tagPrefix + id);
+        JcloudsNodeLauncherConfig config = getActiveConfig();
+        NodeMetadata nodeMetadata = getNodeMetadataForRunningNodeWithTag(config.getTagPrefix()
+ id, config);
         if (nodeMetadata == null) {
             return null;
         }
@@ -284,9 +309,14 @@ public class AmazonNodeLauncher implemen
         return result;
     }
 
-    private NodeMetadata getNodeMetadataForRunningNodeWithTag(String tag) {
-        for (ComputeMetadata node : m_computeServiceContext.getComputeService().listNodes())
{
-            NodeMetadata candidate = m_computeServiceContext.getComputeService().getNodeMetadata(node.getId());
+    private JcloudsNodeLauncherConfig getActiveConfig() {
+        return m_currentConfig != null ? m_currentConfig : m_defaultNodeConfig;
+    }
+
+    private NodeMetadata getNodeMetadataForRunningNodeWithTag(String tag, JcloudsNodeLauncherConfig
config) {
+
+        for (ComputeMetadata node : config.getComputeService().listNodes()) {
+            NodeMetadata candidate = config.getComputeService().getNodeMetadata(node.getId());
             if (tag.equals(candidate.getGroup()) && candidate.getState().equals(NodeState.RUNNING))
{
                 return candidate;
             }
@@ -299,11 +329,11 @@ public class AmazonNodeLauncher implemen
             URL server;
             try {
                 server = new URL(getConfigProperty(properties, SERVER));
-            }
-            catch (MalformedURLException e) {
+            } catch (MalformedURLException e) {
                 throw new ConfigurationException(SERVER, getConfigProperty(properties, SERVER)
+ " is not a valid URL.", e);
             }
             String amiId = getConfigProperty(properties, AMI_ID);
+            String amiOwnerId = getConfigProperty(properties, AMI_OWNER_ID, "");
             String location = getConfigProperty(properties, LOCATION);
             String hardwareId = getConfigProperty(properties, HARDWARE_ID, InstanceType.C1_MEDIUM);
             String accessKeyId = getConfigProperty(properties, ACCESS_KEY_ID);
@@ -319,27 +349,36 @@ public class AmazonNodeLauncher implemen
             String aceLauncher = getConfigProperty(properties, ACE_LAUNCHER, "ace-launcher.jar");
             String additionalObrDownloads = getConfigProperty(properties, ADDITIONAL_OBR_DOWNLOADS,
"");
             String externalDownloadUrls = getConfigProperty(properties, EXTERNAL_DOWNLOAD_URLS,
"");
+            String sshUser = getConfigProperty(properties, SSH_USER, "ec2-user");
+
+            m_defaultNodeConfig = new JcloudsNodeLauncherConfig()
+                    .setAccessKeyId(accessKeyId)
+                    .setSecretAccessKey(secretAccessKey)
+                    .setServer(server)
+                    .setImageId(amiId)
+                    .setImageOwnerId(amiOwnerId)
+                    .setLocation(location)
+                    .setHardwareId(hardwareId)
+                    .setKeyPair(keyPair)
+                    .setPrivateKeyFile(privateKeyFile)
+                    .setTagPrefix(tagPrefix)
+                    .setVmOptions(vmOptions)
+                    .setLauncherArguments(launcherArguments)
+                    .setExtraPorts(extraPorts)
+                    .setRunAsRoot(Boolean.parseBoolean(runAsRoot))
+                    .setAccessKeyId(accessKeyId)
+                    .setSecretAccessKey(secretAccessKey)
+                    .setNodeBootstrap(nodeBootstrap)
+                    .setAceLauncher(aceLauncher)
+                    .setAdditionalObrDownloads(additionalObrDownloads)
+                    .setExternalDownloadUrls(externalDownloadUrls)
+                    .setSshUser(sshUser);
 
-            m_server = server;
-            m_amiId = amiId;
-            m_location = location;
-            m_hardwareId = hardwareId;
-            m_accessKeyId = accessKeyId;
-            m_secretAccessKey = secretAccessKey;
-            m_keypair = keyPair;
-            m_privateKeyFile = privateKeyFile;
-            m_tagPrefix = tagPrefix;
-            m_vmOptions = vmOptions;
-            m_nodeBootstrap = nodeBootstrap;
-            m_launcherArguments = launcherArguments;
-            m_extraPorts = extraPorts;
-            m_runAsRoot = "true".equals(runAsRoot);
-            m_aceLauncher = aceLauncher;
-            m_additionalObrDownloads = additionalObrDownloads;
-            m_externalDownloadUrls = externalDownloadUrls;
+            m_defaultNodeConfig.createComputeServiceContext();
         }
     }
 
+
     private String getConfigProperty(@SuppressWarnings("rawtypes") Dictionary settings, String
id) throws ConfigurationException {
         return getConfigProperty(settings, id, null);
     }
@@ -349,11 +388,24 @@ public class AmazonNodeLauncher implemen
         if (result == null) {
             if (defaultValue == null) {
                 throw new ConfigurationException(id, "key missing");
-            }
-            else {
+            } else {
                 return defaultValue;
             }
         }
         return result;
     }
+
+    public void stop() {
+        if (m_currentConfig != null) {
+            m_currentConfig.close();
+        }
+    }
+
+    public NodeLauncherConfig getDefaultConfig() {
+        return m_defaultNodeConfig;
+    }
+
+    public JcloudsNodeLauncherConfig getCurrentConfig() {
+        return m_currentConfig;
+    }
 }

Added: ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java?rev=1348558&view=auto
==============================================================================
--- ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
(added)
+++ ace/trunk/ace-nodelauncher-amazon/src/main/java/org/apache/ace/nodelauncher/amazon/JcloudsNodeLauncherConfig.java
Sun Jun 10 09:56:35 2012
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ace.nodelauncher.amazon;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.apache.ace.nodelauncher.NodeLauncherConfig;
+import org.jclouds.aws.ec2.reference.AWSEC2Constants;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.ComputeServiceContextFactory;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.sshj.config.SshjSshClientModule;
+
+import java.net.URL;
+import java.util.Properties;
+import java.util.Set;
+
+public class JcloudsNodeLauncherConfig implements NodeLauncherConfig {
+    private ComputeServiceContext m_computeServiceContext;
+    
+    private URL m_server;
+    private String m_hardwareId;
+    private String m_ImageId;
+    private String m_ImageOwnerId;
+    private String m_location;
+    private String m_tagPrefix;
+    private String[] m_extraPorts;
+    private boolean m_runAsRoot;
+    private String m_keyPair;
+    private String m_privateKeyFile;
+    private String m_vmOptions;
+    private String m_launcherArguments;
+
+    private String m_accessKeyId;
+    private String m_secretAccessKey;
+    
+    private String m_nodeBootstrap;
+    private String m_aceLauncher;
+    private String m_additionalObrDownloads;
+    private String m_externalDownloadUrls;
+    private String m_sshUser;
+
+    public URL getServer() {
+        return m_server;
+    }
+
+    public JcloudsNodeLauncherConfig setServer(URL server) {
+        m_server = server;
+        return this;
+    }
+
+    public String getHardwareId() {
+        return m_hardwareId;
+    }
+
+    public JcloudsNodeLauncherConfig setHardwareId(String hardwareId) {
+        m_hardwareId = hardwareId;
+        return this;
+    }
+
+    public String getImageId() {
+        return m_ImageId;
+    }
+
+    public JcloudsNodeLauncherConfig setImageId(String m_ImageId) {
+        this.m_ImageId = m_ImageId;
+        return this;
+    }
+
+    public String getImageOwnerId() {
+        return m_ImageOwnerId;
+    }
+
+    public String getTagPrefix() {
+        return m_tagPrefix;
+    }
+
+    public JcloudsNodeLauncherConfig setTagPrefix(String tagPrefix) {
+        this.m_tagPrefix = tagPrefix;
+        return this;
+    }
+
+    public String getLocation() {
+        return m_location;
+    }
+
+    public JcloudsNodeLauncherConfig setLocation(String location) {
+        m_location = location;
+        return this;
+    }
+
+    public String[] getExtraPorts() {
+        return m_extraPorts;
+    }
+
+    public JcloudsNodeLauncherConfig setExtraPorts(String... extraPorts) {
+        m_extraPorts = extraPorts;
+        return this;
+    }
+
+    public boolean isRunAsRoot() {
+        return m_runAsRoot;
+    }
+
+    public JcloudsNodeLauncherConfig setRunAsRoot(boolean runAsRoot) {
+        m_runAsRoot = runAsRoot;
+        return this;
+    }
+
+    public String getKeyPair() {
+        return m_keyPair;
+    }
+
+    public JcloudsNodeLauncherConfig setKeyPair(String keyPair) {
+        m_keyPair = keyPair;
+        return this;
+    }
+
+    public String getPrivateKeyFile() {
+        return m_privateKeyFile;
+    }
+
+    public JcloudsNodeLauncherConfig setPrivateKeyFile(String privateKeyFile) {
+        m_privateKeyFile = privateKeyFile;
+        return this;
+    }
+
+    public String getVmOptions() {
+        return m_vmOptions;
+    }
+
+    public JcloudsNodeLauncherConfig setVmOptions(String vmOptions) {
+        m_vmOptions = vmOptions;
+        return this;
+    }
+
+    public String getLauncherArguments() {
+        return m_launcherArguments;
+    }
+
+    public JcloudsNodeLauncherConfig setLauncherArguments(String launcherArguments) {
+        m_launcherArguments = launcherArguments;
+        return this;
+    }
+
+    public Set<? extends Hardware> listHardwareIds() {
+        return m_computeServiceContext.getComputeService().listHardwareProfiles();
+    }
+
+    public Set<? extends Image> listImages() {
+        return m_computeServiceContext.getComputeService().listImages();
+    }
+
+    public JcloudsNodeLauncherConfig setImageOwnerId(String imageOwnerId) {
+        m_ImageOwnerId = imageOwnerId;
+        createComputeServiceContext();
+
+        return this;
+    }
+
+    public String getAccessKeyId() {
+        return m_accessKeyId;
+    }
+
+    public JcloudsNodeLauncherConfig setAccessKeyId(String accessKeyId) {
+        m_accessKeyId = accessKeyId;
+        return this;
+    }
+
+    public String getSecretAccessKey() {
+        return m_secretAccessKey;
+    }
+
+    public JcloudsNodeLauncherConfig setSecretAccessKey(String secretAccessKey) {
+        m_secretAccessKey = secretAccessKey;
+        return this;
+    }
+
+    public String getNodeBootstrap() {
+        return m_nodeBootstrap;
+    }
+
+    public JcloudsNodeLauncherConfig setNodeBootstrap(String nodeBootstrap) {
+        m_nodeBootstrap = nodeBootstrap;
+        return this;
+    }
+
+    public String getAceLauncher() {
+        return m_aceLauncher;
+    }
+
+    public JcloudsNodeLauncherConfig setAceLauncher(String aceLauncher) {
+        m_aceLauncher = aceLauncher;
+        return this;
+    }
+
+    public String getAdditionalObrDownloads() {
+        return m_additionalObrDownloads;
+    }
+
+    public JcloudsNodeLauncherConfig setAdditionalObrDownloads(String additionalObrDownloads)
{
+        m_additionalObrDownloads = additionalObrDownloads;
+        return this;
+    }
+
+    public String getExternalDownloadUrls() {
+        return m_externalDownloadUrls;
+    }
+
+    public JcloudsNodeLauncherConfig setExternalDownloadUrls(String externalDownloadUrls)
{
+        m_externalDownloadUrls = externalDownloadUrls;
+        return this;
+    }
+
+    public String getSshUser() {
+        return m_sshUser;
+    }
+
+    public JcloudsNodeLauncherConfig setSshUser(String sshUser) {
+        this.m_sshUser = sshUser;
+        return this;
+    }
+
+    /**
+     * Recreate the ComputeServiceContext. This is required after setting some properties
to have an effect (e.g. changing ImageOwnerId).
+     * This is an expensive operation, only call when required.
+     */
+    public void createComputeServiceContext() {
+        if (m_computeServiceContext != null) {
+            m_computeServiceContext.close();
+        }
+
+        Properties props = new Properties();
+        if (m_ImageOwnerId != null && m_ImageOwnerId.length() > 0) {
+            props.setProperty(AWSEC2Constants.PROPERTY_EC2_AMI_QUERY, "owner-id=" + m_ImageOwnerId
+ ";state=available;image-type=machine;root-device-type=ebs");
+            props.setProperty(AWSEC2Constants.PROPERTY_EC2_CC_AMI_QUERY, "");
+        }
+
+        m_computeServiceContext = new ComputeServiceContextFactory().createContext("aws-ec2",
m_accessKeyId, m_secretAccessKey, ImmutableSet.<Module>of(new SshjSshClientModule()),
props);
+    }
+
+    public ComputeService getComputeService() {
+        return m_computeServiceContext.getComputeService();
+    }
+
+    public void close() {
+        if(m_computeServiceContext != null) {
+            m_computeServiceContext.close();
+        }
+    }
+}

Modified: ace/trunk/ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/PortParseTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/PortParseTest.java?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/PortParseTest.java
(original)
+++ ace/trunk/ace-nodelauncher-amazon/src/test/java/org/apache/ace/nodelauncher/amazon/PortParseTest.java
Sun Jun 10 09:56:35 2012
@@ -8,10 +8,9 @@ public class PortParseTest {
     @Test(groups = { UNIT })
     public void testParsePortsFromString() throws Exception {
         AmazonNodeLauncher instance = new AmazonNodeLauncher();
-        Assert.assertTrue(assertEquals(instance.parseExtraPorts("1,2,3"), new int[] {1, 2,
3}));
-        Assert.assertTrue(assertEquals(instance.parseExtraPorts(""), new int[] {}));
-        Assert.assertTrue(assertEquals(instance.parseExtraPorts("1 ,2 , 3 "), new int[] {1,
2, 3}));
-        Assert.assertTrue(assertEquals(instance.parseExtraPorts("800,900"), new int[] {800,
900}));
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {"1", "2", "3"}),
new int[] {1, 2, 3}));
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {}), new int[]
{}));
+        Assert.assertTrue(assertEquals(instance.parseExtraPorts(new String[] {"800","900"}),
new int[] {800, 900}));
     }
     
     @Test(groups = { UNIT })

Modified: ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncher.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncher.java?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncher.java
(original)
+++ ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncher.java
Sun Jun 10 09:56:35 2012
@@ -38,11 +38,32 @@ public interface NodeLauncher {
     void start(String id) throws Exception;
 
     /**
+     * Starts a new node with the given ID. Does not check whether this ID is already in
use.
+     * The provided properties override the configuration provided in configuration. Depending
on the underlying
+     * provider this could be used to specify a node type, image id etc.
+     * @param id A textual ID for the node.
+     * @param config Configuration object to override configuration properties such as node
type.
+     * @throws Exception Be aware that the implementation may pass through implementation-specific
exceptions.
+     */
+    void start(String id, NodeLauncherConfig config) throws Exception;
+
+    /**
      * Destroys the node with the given ID. Does not check whether this ID actually exists.
      * @param id A textual ID for the node.
      * @throws Exception Be aware that the implementation may pass through implementation-specific
exceptions.
      */
     void stop(String id) throws Exception;
+
+    /**
+     * If available, return a default configuration object. May return null if not available
in an implementation.
+     * @return Default launcher configuration, or null if not available.
+     */
+    NodeLauncherConfig getDefaultConfig();
+
+    /**
+     * @return  The currently set configuration object if available, or null if not available.
+     */
+    NodeLauncherConfig getCurrentConfig();
     
     /**
      * Retrieves properties from the node. These will include, at least

Added: ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncherConfig.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncherConfig.java?rev=1348558&view=auto
==============================================================================
--- ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncherConfig.java
(added)
+++ ace/trunk/ace-nodelauncher-api/src/main/java/org/apache/ace/nodelauncher/NodeLauncherConfig.java
Sun Jun 10 09:56:35 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.ace.nodelauncher;
+
+/**
+ * Empty interface that should be implemented by NodeLauncherConfig implmentation. The interface
is empty
+ * because configuration is very different for each kind of node (e.g. an embedded node vs
a jclouds node) it's
+ * not possible to have a standard interface for configuration.
+ * The interface is required however so that the NodeLauncherConfig can still be independent
of specific node types.
+ * Clients of this interface (e.g. UI) should cast this interface to the concrete implementation
it's built for.
+ *
+ */
+public interface NodeLauncherConfig {
+
+}

Modified: ace/trunk/ace-nodelauncher-ui/pom.xml
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-ui/pom.xml?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-ui/pom.xml (original)
+++ ace/trunk/ace-nodelauncher-ui/pom.xml Sun Jun 10 09:56:35 2012
@@ -65,7 +65,7 @@
         </dependency>
         <dependency>
             <groupId>org.apache.ace</groupId>
-            <artifactId>org.apache.ace.nodelauncher.api</artifactId>
+            <artifactId>org.apache.ace.nodelauncher.amazon</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.ace</groupId>

Modified: ace/trunk/ace-nodelauncher-ui/src/main/java/org/apache/ace/nodelauncher/ui/NodePanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-nodelauncher-ui/src/main/java/org/apache/ace/nodelauncher/ui/NodePanel.java?rev=1348558&r1=1348557&r2=1348558&view=diff
==============================================================================
--- ace/trunk/ace-nodelauncher-ui/src/main/java/org/apache/ace/nodelauncher/ui/NodePanel.java
(original)
+++ ace/trunk/ace-nodelauncher-ui/src/main/java/org/apache/ace/nodelauncher/ui/NodePanel.java
Sun Jun 10 09:56:35 2012
@@ -18,16 +18,19 @@
  */
 package org.apache.ace.nodelauncher.ui;
 
+import com.vaadin.data.Property;
+import com.vaadin.ui.*;
+import com.vaadin.ui.Button.ClickListener;
+import org.apache.ace.nodelauncher.amazon.JcloudsNodeLauncherConfig;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.osgi.service.log.LogService;
+
 import java.util.*;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
-import com.vaadin.ui.*;
-import org.osgi.service.log.LogService;
-
-import com.vaadin.ui.Button.ClickListener;
-
 @SuppressWarnings("serial")
 public class NodePanel extends Panel {
     private final String m_targetId;
@@ -36,7 +39,25 @@ public class NodePanel extends Panel {
     private final NodeLauncherPanelFactory m_factory;
     private final Map<Action, Runnable> m_runners = new HashMap<Action, Runnable>();
     private final Runnable m_statusGetter = new StatusGetter();
-    
+    private TextField m_locationInput;
+    private Select m_hardwareIdSelect;
+    private TextField m_ImageOwnerIdInput;
+    private Select m_ImageIdSelect;
+    private TextField m_keyPairInput;
+    private TextField m_tagPrefixInput;
+    private TextField m_extraPortsInput;
+    private CheckBox m_runAsRootCheckbox;
+    private TextField m_privateKeyFileInput;
+    private TextField m_vmOptionsInput;
+    private TextField m_launcherArgumentsInput;
+    private TextField m_nodeBootstrapInput;
+    private TextField m_aceLauncherInput;
+    private TextField m_additionalObrDownloadsInput;
+    private TextField m_externalDownloadsInput;
+    private TextField m_sshUserInput;
+
+    private JcloudsNodeLauncherConfig config;
+
     {
         m_runners.put(Action.Start, new StartRunner());
         m_runners.put(Action.Stop, new StopRunner());
@@ -45,6 +66,7 @@ public class NodePanel extends Panel {
     public NodePanel(NodeLauncherPanelFactory factory, String target) {
         m_factory = factory;
         m_targetId = target;
+        config = (JcloudsNodeLauncherConfig)m_factory.getCloudService().getDefaultConfig();
         setContent();
         setCaption(m_targetId);
     }
@@ -64,17 +86,108 @@ public class NodePanel extends Panel {
         buttonPanel.addComponent(startButton);
         buttonPanel.addComponent(stopButton);
         buttonPanel.setSpacing(true);
+        
 
         Table propertiesTable = new PropertiesTable(m_handler);
         propertiesTable.setWidth("100%");
 
         panel.addComponent(status);
         panel.addComponent(buttonPanel);
+
+        m_locationInput = new TextField("Location", config.getLocation());
+        panel.addComponent(m_locationInput);
+
+        Set<? extends Hardware> hardwares = config.listHardwareIds();
+
+        m_hardwareIdSelect = new Select("Node type");
+        createHardwareItems(hardwares);
+        panel.addComponent(m_hardwareIdSelect);
+
+        m_ImageOwnerIdInput = new TextField("Image owner ID", config.getImageOwnerId());
+
+        panel.addComponent(m_ImageOwnerIdInput);
+
+        m_ImageIdSelect = new Select("Image ID");
+        createImageItems();
+        panel.addComponent(m_ImageIdSelect);
+
+        m_ImageOwnerIdInput.addListener(new Property.ValueChangeListener() {
+            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
+                config.setImageOwnerId((String) valueChangeEvent.getProperty().getValue());
+                m_ImageIdSelect.removeAllItems();
+
+                createImageItems();
+            }
+        });
+
+
+        m_keyPairInput = new TextField("Keypair", config.getKeyPair());
+        panel.addComponent(m_keyPairInput);
+
+        m_tagPrefixInput = new TextField("Tag prefix", config.getTagPrefix());
+        panel.addComponent(m_tagPrefixInput);
+
+        String[] extraPorts = config.getExtraPorts();
+        StringBuilder extraPortsValue = new StringBuilder();
+        for (String extraPort : extraPorts) {
+            extraPortsValue.append(extraPort).append(",");
+        }
+        m_extraPortsInput = new TextField("Extra ports (comma separated", extraPortsValue.toString());
+        panel.addComponent(m_extraPortsInput);
+
+        m_runAsRootCheckbox = new CheckBox("Run as root", config.isRunAsRoot());
+        panel.addComponent(m_runAsRootCheckbox);
+
+        m_privateKeyFileInput = new TextField("Private key file", config.getPrivateKeyFile());
+        panel.addComponent(m_privateKeyFileInput);
+
+        m_vmOptionsInput = new TextField("VM options", config.getVmOptions());
+        panel.addComponent(m_vmOptionsInput);
+
+        m_launcherArgumentsInput = new TextField("Launcher arguments", config.getLauncherArguments());
+        panel.addComponent(m_launcherArgumentsInput);
+
+        m_nodeBootstrapInput = new TextField("Node bootstrap script", config.getNodeBootstrap());
+        panel.addComponent(m_nodeBootstrapInput);
+
+        m_aceLauncherInput = new TextField("ACE launcher", config.getAceLauncher());
+        panel.addComponent(m_aceLauncherInput);
+
+        m_additionalObrDownloadsInput = new TextField("Additional OBR downloads (comma separated",
config.getAdditionalObrDownloads());
+        panel.addComponent(m_additionalObrDownloadsInput);
+
+        m_externalDownloadsInput = new TextField("External download urls (comman separated",
config.getExternalDownloadUrls());
+        panel.addComponent(m_externalDownloadsInput);
+
+        m_sshUserInput = new TextField("SSH username", "ec2-user");
+        panel.addComponent(m_sshUserInput);
+
         panel.addComponent(propertiesTable);
 
         m_factory.submit(m_statusGetter);
     }
 
+    private void createHardwareItems(Set<? extends Hardware> hardwares) {
+        for (Hardware hardware : hardwares) {
+            m_hardwareIdSelect.addItem(hardware.getId());
+            m_hardwareIdSelect.setItemCaption(hardware.getId(), hardware.getName());
+            if(hardware.getId().equals(config.getHardwareId())) {
+                m_hardwareIdSelect.select(hardware.getId());
+            }
+        }
+    }
+
+    private void createImageItems() {
+        Set<? extends Image> images = config.listImages();
+        for (Image image : images) {
+            m_ImageIdSelect.addItem(image.getId());
+            m_ImageIdSelect.setItemCaption(image.getId(), image.getName());
+            if(image.getId().endsWith(config.getImageId())) {
+                m_ImageIdSelect.select(image.getId());
+            }
+        }
+    }
+
     @SuppressWarnings("serial")
     private class ActionButton extends Button implements NodeStatusHandler.NodeStatusListener,
ClickListener {
         private final Action m_action;
@@ -158,8 +271,49 @@ public class NodePanel extends Panel {
         protected void doRun() {
             try {
                 m_handler.setStatus(NodeStatus.STARTING);
-                m_factory.getCloudService().start(m_targetId);
+
+                String sshUser = (String) m_sshUserInput.getValue();
+                String location = (String) m_locationInput.getValue();
+                String hardwareId = (String) m_hardwareIdSelect.getValue();
+                String imageOwnerId = (String) m_ImageOwnerIdInput.getValue();
+                String imageId = (String) m_ImageIdSelect.getValue();
+                String keyPair = (String) m_keyPairInput.getValue();
+                String tagPrefix = (String) m_tagPrefixInput.getValue();
+                String[] extraPorts = ((String)m_extraPortsInput.getValue()).split(",");
+                boolean runAsRoot = m_runAsRootCheckbox.booleanValue();
+                String privateKeyFile = (String)m_privateKeyFileInput.getValue();
+                String vmOptions = (String)m_vmOptionsInput.getValue();
+                String laucherArgs = (String)m_launcherArgumentsInput.getValue();
+                String nodeBootStrap = (String)m_nodeBootstrapInput.getValue();
+                String aceLauncher = (String)m_aceLauncherInput.getValue();
+                String additionalObrDownloads = (String)m_additionalObrDownloadsInput.getValue();
+                String externalDownloads = (String)m_externalDownloadsInput.getValue();
+
+                config.setSshUser(sshUser);
+                config.setLocation(location);
+                config.setHardwareId(hardwareId);
+
+                if(imageOwnerId.length() > 0) {
+                    config.setImageOwnerId(imageOwnerId);
+                }
+
+                config.setImageId(imageId);
+                config.setKeyPair(keyPair);
+                config.setTagPrefix(tagPrefix);
+                config.setExtraPorts(extraPorts);
+                config.setRunAsRoot(runAsRoot);
+                config.setPrivateKeyFile(privateKeyFile);
+                config.setVmOptions(vmOptions);
+                config.setLauncherArguments(laucherArgs);
+                config.setNodeBootstrap(nodeBootStrap);
+                config.setAceLauncher(aceLauncher);
+                config.setAdditionalObrDownloads(additionalObrDownloads);
+                config.setExternalDownloadUrls(externalDownloads);
+
+                m_factory.getCloudService().start(m_targetId, config);
                 m_handler.setStatus(NodeStatus.INITIALIZING);
+                disableInputFields();
+
             }
             catch (Exception e) {
                 m_handler.setStatus(NodeStatus.ERROR);
@@ -168,7 +322,25 @@ public class NodePanel extends Panel {
             m_factory.submit(m_statusGetter);
         }
     }
-    
+
+    private void disableInputFields() {
+        m_locationInput.setEnabled(false);
+        m_hardwareIdSelect.setEnabled(false);
+        m_ImageOwnerIdInput.setEnabled(false);
+        m_ImageIdSelect.setEnabled(false);
+        m_keyPairInput.setEnabled(false);
+        m_tagPrefixInput.setEnabled(false);
+        m_extraPortsInput.setEnabled(false);
+        m_runAsRootCheckbox.setEnabled(false);
+        m_privateKeyFileInput.setEnabled(false);
+        m_vmOptionsInput.setEnabled(false);
+        m_launcherArgumentsInput.setEnabled(false);
+        m_nodeBootstrapInput.setEnabled(false);
+        m_aceLauncherInput.setEnabled(false);
+        m_additionalObrDownloadsInput.setEnabled(false);
+        m_externalDownloadsInput.setEnabled(false);
+    }
+
     private class StopRunner extends LockedRunner {
         @Override
         protected void doRun() {



Mime
View raw message