@Test
 public void testLaunchCluster() throws RunNodesException {
   int numNodes = 3;
   final String clusterName = "test-launch-cluster";
   Set<? extends NodeMetadata> nodes =
       context
           .getComputeService()
           .createNodesInGroup(
               clusterName,
               numNodes,
               TemplateOptions.Builder.overrideLoginUser("toor")
                   .runScript(AdminAccess.standard()));
   assertEquals(numNodes, nodes.size(), "wrong number of nodes");
   for (NodeMetadata node : nodes) {
     assertEquals("test-launch-cluster", node.getGroup());
     logger.debug("Created Node: %s", node);
     SshClient client = context.utils().sshForNode().apply(node);
     client.connect();
     ExecResponse hello = client.exec("echo hello");
     assertEquals(hello.getOutput().trim(), "hello");
   }
   context
       .getComputeService()
       .destroyNodesMatching(
           new Predicate<NodeMetadata>() {
             @Override
             public boolean apply(NodeMetadata input) {
               return input.getId().contains(clusterName);
             }
           });
 }
  // Suggest at least 15 minutes for timeout
  public static String waitForPasswordOnAws(
      ComputeService computeService, final NodeMetadata node, long timeout, TimeUnit timeUnit)
      throws TimeoutException {
    ComputeServiceContext computeServiceContext = computeService.getContext();
    AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class);
    final WindowsApi client = ec2Client.getWindowsApi().get();
    final String region = node.getLocation().getParent().getId();

    // The Administrator password will take some time before it is ready - Amazon says sometimes 15
    // minutes.
    // So we create a predicate that tests if the password is ready, and wrap it in a retryable
    // predicate.
    Predicate<String> passwordReady =
        new Predicate<String>() {
          @Override
          public boolean apply(String s) {
            if (Strings.isNullOrEmpty(s)) return false;
            PasswordData data = client.getPasswordDataInRegion(region, s);
            if (data == null) return false;
            return !Strings.isNullOrEmpty(data.getPasswordData());
          }
        };

    LOG.info("Waiting for password, for " + node.getProviderId() + ":" + node.getId());
    Predicate<String> passwordReadyRetryable =
        Predicates2.retry(
            passwordReady, timeUnit.toMillis(timeout), 10 * 1000, TimeUnit.MILLISECONDS);
    boolean ready = passwordReadyRetryable.apply(node.getProviderId());
    if (!ready)
      throw new TimeoutException(
          "Password not available for "
              + node
              + " in region "
              + region
              + " after "
              + timeout
              + " "
              + timeUnit.name());

    // Now pull together Amazon's encrypted password blob, and the private key that jclouds
    // generated
    PasswordDataAndPrivateKey dataAndKey =
        new PasswordDataAndPrivateKey(
            client.getPasswordDataInRegion(region, node.getProviderId()),
            node.getCredentials().getPrivateKey());

    // And apply it to the decryption function
    WindowsLoginCredentialsFromEncryptedData f =
        computeServiceContext
            .utils()
            .injector()
            .getInstance(WindowsLoginCredentialsFromEncryptedData.class);
    LoginCredentials credentials = f.apply(dataAndKey);

    return credentials.getPassword();
  }
  public static String getFirstReachableAddress(ComputeServiceContext context, NodeMetadata node) {
    // To pick the address, it relies on jclouds `sshForNode().apply(Node)` to check all IPs of node
    // (private+public),
    // to find one that is reachable. It does `openSocketFinder.findOpenSocketOnNode(node,
    // node.getLoginPort(), ...)`.
    // This keeps trying for time
    // org.jclouds.compute.reference.ComputeServiceConstants.Timeouts.portOpen.
    // TODO Want to configure this timeout here.
    //
    // TODO We could perhaps instead just set `templateOptions.blockOnPort(loginPort, 120)`, but
    // need
    // to be careful to only set that if config WAIT_FOR_SSHABLE is true. For some advanced
    // networking examples
    // (e.g. using DNAT on CloudStack), the brooklyn machine won't be able to reach the VM until
    // some additional
    // setup steps have been done. See links from Andrea:
    //     https://github.com/jclouds/jclouds/pull/895
    //     https://issues.apache.org/jira/browse/WHIRR-420
    //     jclouds.ssh.max-retries
    //     jclouds.ssh.retry-auth

    SshClient client;
    try {
      client = context.utils().sshForNode().apply(node);
    } catch (Exception e) {
      Exceptions.propagateIfFatal(e);
      /* i've seen: java.lang.IllegalStateException: Optional.get() cannot be called on an absent value
       * from org.jclouds.crypto.ASN1Codec.createASN1Sequence(ASN1Codec.java:86), if the ssh key has a passphrase, against AWS.
       *
       * others have reported: java.lang.IllegalArgumentException: DER length more than 4 bytes
       * when using a key with a passphrase (perhaps from other clouds?); not sure if that's this callpath or a different one.
       */
      throw new IllegalStateException(
          "Unable to connect SshClient to "
              + node
              + "; check that the node is accessible and that the SSH key exists and is correctly configured, including any passphrase defined",
          e);
    }
    return client.getHostAddress();
  }
 public static CloudTransformer tranformerFor(ComputeServiceContext source, String target) {
   return checkNotNull(
       source.utils().injector().getInstance(Key.get(mapOfString)).get(target),
       " no transformer were registered for targget cloud: " + target);
 }
Esempio n. 5
0
 protected Logger logger() {
   return context.utils().loggerFactory().getLogger("jclouds.compute");
 }