@Override
  public Collection<? extends Action> getProjectActions(AbstractProject<?, ?> project) {
    ArrayList<TestflightBuildAction> actions = new ArrayList<TestflightBuildAction>();
    RunList<? extends AbstractBuild<?, ?>> builds = project.getBuilds();

    Collection predicated =
        CollectionUtils.select(
            builds,
            new Predicate() {
              public boolean evaluate(Object o) {
                Result result = ((AbstractBuild<?, ?>) o).getResult();
                if (result == null) return false; // currently running builds can have a null result
                return result.isBetterOrEqualTo(Result.SUCCESS);
              }
            });

    ArrayList<AbstractBuild<?, ?>> filteredList = new ArrayList<AbstractBuild<?, ?>>(predicated);

    Collections.reverse(filteredList);
    for (AbstractBuild<?, ?> build : filteredList) {
      List<TestflightBuildAction> testflightActions = build.getActions(TestflightBuildAction.class);
      if (testflightActions != null && testflightActions.size() > 0) {
        for (TestflightBuildAction action : testflightActions) {
          actions.add(new TestflightBuildAction(action));
        }
        break;
      }
    }

    return actions;
  }
 @Override
 public synchronized List<Action> getActions() {
   List<Action> actions = new ArrayList<Action>();
   actions.add(new GitFeedAction());
   actions.add(new ClearCaseUCMFeedAction());
   return actions;
 }
  @Override
  public boolean perform(
      AbstractBuild<?, ?> build, Launcher launcher, final BuildListener listener) {
    if (build.getResult().isWorseOrEqualTo(Result.FAILURE)) return false;

    listener.getLogger().println(Messages.TestflightRecorder_InfoUploading());

    try {
      EnvVars vars = build.getEnvironment(listener);

      String workspace = vars.expand("$WORKSPACE");

      List<TestflightUploader.UploadRequest> urList =
          new ArrayList<TestflightUploader.UploadRequest>();

      for (TestflightTeam team : createDefaultPlusAdditionalTeams()) {
        try {
          TestflightUploader.UploadRequest ur = createPartialUploadRequest(team, vars, build);
          urList.add(ur);
        } catch (MisconfiguredJobException mje) {
          listener.getLogger().println(mje.getConfigurationMessage());
          return false;
        }
      }

      for (TestflightUploader.UploadRequest ur : urList) {
        TestflightRemoteRecorder remoteRecorder =
            new TestflightRemoteRecorder(workspace, ur, listener);

        final List<Map> parsedMaps;

        try {
          Object result = launcher.getChannel().call(remoteRecorder);
          parsedMaps = (List<Map>) result;
        } catch (UploadException ue) {
          listener
              .getLogger()
              .println(Messages.TestflightRecorder_IncorrectResponseCode(ue.getStatusCode()));
          listener.getLogger().println(ue.getResponseBody());
          return false;
        }

        if (parsedMaps.size() == 0) {
          listener.getLogger().println(Messages.TestflightRecorder_NoUploadedFile(ur.filePaths));
          return false;
        }
        for (Map parsedMap : parsedMaps) {
          addTestflightLinks(build, listener, parsedMap);
        }
      }
    } catch (Throwable e) {
      listener.getLogger().println(e);
      e.printStackTrace(listener.getLogger());
      return false;
    }

    return true;
  }
Esempio n. 4
0
  /**
   * Possibly empty list of all disabled modules (if disabled==true) or all enabeld modules (if
   * disabled==false)
   */
  public List<MavenModule> getDisabledModules(boolean disabled) {
    if (!disabled && sortedActiveModules != null) return sortedActiveModules;

    List<MavenModule> r = new ArrayList<MavenModule>();
    for (MavenModule m : modules.values()) {
      if (m.isDisabled() == disabled) r.add(m);
    }
    return r;
  }
 private List<TestflightTeam> createDefaultPlusAdditionalTeams() {
   List<TestflightTeam> allTeams = new ArrayList<TestflightTeam>();
   // first team is default
   allTeams.add(new TestflightTeam(getTokenPairName(), getFilePath(), getDsymPath()));
   if (additionalTeams != null) {
     allTeams.addAll(Arrays.asList(additionalTeams));
   }
   return allTeams;
 }
Esempio n. 6
0
 /** Returns the {@link MavenModule}s that are in the queue. */
 public List<Queue.Item> getQueueItems() {
   List<Queue.Item> r = new ArrayList<hudson.model.Queue.Item>();
   for (Queue.Item item : Hudson.getInstance().getQueue().getItems()) {
     Task t = item.task;
     if ((t instanceof MavenModule && ((MavenModule) t).getParent() == this) || t == this)
       r.add(item);
   }
   return r;
 }
Esempio n. 7
0
  /** Get a list of security group ids for the slave */
  private List<String> getEc2SecurityGroups(AmazonEC2 ec2) throws AmazonClientException {
    List<String> groupIds = new ArrayList<String>();

    DescribeSecurityGroupsResult groupResult =
        getSecurityGroupsBy("group-name", securityGroupSet, ec2);
    if (groupResult.getSecurityGroups().size() == 0) {
      groupResult = getSecurityGroupsBy("group-id", securityGroupSet, ec2);
    }

    for (SecurityGroup group : groupResult.getSecurityGroups()) {
      if (group.getVpcId() != null && !group.getVpcId().isEmpty()) {
        List<Filter> filters = new ArrayList<Filter>();
        filters.add(new Filter("vpc-id").withValues(group.getVpcId()));
        filters.add(new Filter("state").withValues("available"));
        filters.add(new Filter("subnet-id").withValues(getSubnetId()));

        DescribeSubnetsRequest subnetReq = new DescribeSubnetsRequest();
        subnetReq.withFilters(filters);
        DescribeSubnetsResult subnetResult = ec2.describeSubnets(subnetReq);

        List<Subnet> subnets = subnetResult.getSubnets();
        if (subnets != null && !subnets.isEmpty()) {
          groupIds.add(group.getGroupId());
        }
      }
    }

    if (securityGroupSet.size() != groupIds.size()) {
      throw new AmazonClientException(
          "Security groups must all be VPC security groups to work in a VPC context");
    }

    return groupIds;
  }
 /** Compiles all the patterns from {@link #getLogPattern()} */
 private List<Pattern> createPatternsList() {
   String logPattern = getLogPattern();
   if (logPattern == null || logPattern.isEmpty()) {
     return Collections.emptyList();
   }
   List<Pattern> result = new LinkedList<Pattern>();
   Scanner scanner = new Scanner(logPattern);
   while (scanner.hasNextLine()) {
     String line = scanner.nextLine();
     Pattern pattern = Pattern.compile(line);
     result.add(pattern);
   }
   return result;
 }
Esempio n. 9
0
 private List<String> getMavenArgument(String shortForm, String longForm) {
   List<String> args = new ArrayList<String>();
   boolean switchFound = false;
   for (String t : Util.tokenize(getGoals())) {
     if (switchFound) {
       args.add(t);
       switchFound = false;
     } else if (t.equals(shortForm) || t.equals(longForm)) switchFound = true;
     else if (t.startsWith(shortForm)) {
       args.add(t.substring(shortForm.length()));
     } else if (t.startsWith(longForm)) {
       args.add(t.substring(longForm.length()));
     }
   }
   return args;
 }
Esempio n. 10
0
  public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException {
    modules = Collections.emptyMap(); // needed during load
    super.onLoad(parent, name);

    modules =
        loadChildren(
            this,
            getModulesDir(),
            new Function1<ModuleName, MavenModule>() {
              public ModuleName call(MavenModule module) {
                return module.getModuleName();
              }
            });
    // update the transient nest level field.
    MavenModule root = getRootModule();
    if (root != null && root.getChildren() != null) {
      List<MavenModule> sortedList = new ArrayList<MavenModule>();
      Stack<MavenModule> q = new Stack<MavenModule>();
      root.nestLevel = 0;
      q.push(root);
      while (!q.isEmpty()) {
        MavenModule p = q.pop();
        sortedList.add(p);
        List<MavenModule> children = p.getChildren();
        if (children != null) {
          for (MavenModule m : children) m.nestLevel = p.nestLevel + 1;
          for (int i = children.size() - 1; i >= 0; i--) // add them in the reverse order
          q.push(children.get(i));
        }
      }
      this.sortedActiveModules = sortedList;
    } else {
      this.sortedActiveModules = getDisabledModules(false);
    }

    if (reporters == null)
      reporters = new DescribableList<MavenReporter, Descriptor<MavenReporter>>(this);
    reporters.setOwner(this);
    if (publishers == null)
      publishers = new DescribableList<Publisher, Descriptor<Publisher>>(this);
    publishers.setOwner(this);
    if (buildWrappers == null)
      buildWrappers = new DescribableList<BuildWrapper, Descriptor<BuildWrapper>>(this);
    buildWrappers.setOwner(this);

    updateTransientActions();
  }
Esempio n. 11
0
  protected List<Action> createTransientActions() {
    List<Action> r = super.createTransientActions();

    // Fix for ISSUE-1149
    for (MavenModule module : modules.values()) {
      module.updateTransientActions();
    }

    if (publishers
        != null) // this method can be loaded from within the onLoad method, where this might be
      // null
      for (BuildStep step : publishers) r.addAll(step.getProjectActions(this));

    if (buildWrappers != null)
      for (BuildWrapper step : buildWrappers) r.addAll(step.getProjectActions(this));

    return r;
  }
Esempio n. 12
0
  protected void addTransientActionsFromBuild(
      MavenModuleSetBuild build, List<Action> collection, Set<Class> added) {
    if (build == null) return;

    for (Action a : build.getActions())
      if (a instanceof MavenAggregatedReport)
        if (added.add(a.getClass()))
          collection.add(((MavenAggregatedReport) a).getProjectAction(this));

    List<MavenReporter> list = build.projectActionReporters;
    if (list == null) return;

    for (MavenReporter step : list) {
      if (!added.add(step.getClass())) continue; // already added
      Action a = step.getAggregatedProjectAction(this);
      if (a != null) collection.add(a);
    }
  }
Esempio n. 13
0
  private List<BlockDeviceMapping> getNewEphemeralDeviceMapping() {

    final List<BlockDeviceMapping> oldDeviceMapping = getAmiBlockDeviceMappings();

    final Set<String> occupiedDevices = new HashSet<String>();
    for (final BlockDeviceMapping mapping : oldDeviceMapping) {

      occupiedDevices.add(mapping.getDeviceName());
    }

    final List<String> available =
        new ArrayList<String>(
            Arrays.asList("ephemeral0", "ephemeral1", "ephemeral2", "ephemeral3"));

    final List<BlockDeviceMapping> newDeviceMapping = new ArrayList<BlockDeviceMapping>(4);
    for (char suffix = 'b'; suffix <= 'z' && !available.isEmpty(); suffix++) {

      final String deviceName = String.format("/dev/xvd%s", suffix);

      if (occupiedDevices.contains(deviceName)) continue;

      final BlockDeviceMapping newMapping =
          new BlockDeviceMapping().withDeviceName(deviceName).withVirtualName(available.get(0));

      newDeviceMapping.add(newMapping);
      available.remove(0);
    }

    return newDeviceMapping;
  }
  /**
   * Checks if the logs of the given run match any of the given patterns, line-by-line.
   *
   * @param matrixRun The run to be considered.
   * @param patterns The patterns to match with.
   * @return True if at least one line of the logs match at least one of the given patterns.
   * @throws IOException If there's a problem reading the log file.
   */
  private boolean matchesPattern(MatrixRun matrixRun, List<Pattern> patterns) throws IOException {
    if (patterns == null || patterns.isEmpty()) {
      return true; // No specific patterns specified. Accept everything.
    }

    BufferedReader reader =
        new BufferedReader(
            new InputStreamReader(
                new FileInputStream(matrixRun.getLogFile()), matrixRun.getCharset()));
    try {
      for (String line = reader.readLine(); line != null; line = reader.readLine()) {
        for (Pattern pattern : patterns) {
          Matcher matcher = pattern.matcher(line);
          if (matcher.find()) {
            return true;
          }
        }
      }
    } finally {
      reader.close();
    }
    return false;
  }
Esempio n. 15
0
 /** * Check that the AMI requested is available in the cloud and can be used. */
 public FormValidation doValidateAmi(
     @QueryParameter boolean useInstanceProfileForCredentials,
     @QueryParameter String credentialsId,
     @QueryParameter String ec2endpoint,
     @QueryParameter String region,
     final @QueryParameter String ami)
     throws IOException {
   AWSCredentialsProvider credentialsProvider =
       EC2Cloud.createCredentialsProvider(useInstanceProfileForCredentials, credentialsId);
   AmazonEC2 ec2;
   if (region != null) {
     ec2 = EC2Cloud.connect(credentialsProvider, AmazonEC2Cloud.getEc2EndpointUrl(region));
   } else {
     ec2 = EC2Cloud.connect(credentialsProvider, new URL(ec2endpoint));
   }
   if (ec2 != null) {
     try {
       List<String> images = new LinkedList<String>();
       images.add(ami);
       List<String> owners = new LinkedList<String>();
       List<String> users = new LinkedList<String>();
       DescribeImagesRequest request = new DescribeImagesRequest();
       request.setImageIds(images);
       request.setOwners(owners);
       request.setExecutableUsers(users);
       List<Image> img = ec2.describeImages(request).getImages();
       if (img == null || img.isEmpty()) {
         // de-registered AMI causes an empty list to be
         // returned. so be defensive
         // against other possibilities
         return FormValidation.error("No such AMI, or not usable with this accessId: " + ami);
       }
       String ownerAlias = img.get(0).getImageOwnerAlias();
       return FormValidation.ok(
           img.get(0).getImageLocation() + (ownerAlias != null ? " by " + ownerAlias : ""));
     } catch (AmazonClientException e) {
       return FormValidation.error(e.getMessage());
     }
   } else return FormValidation.ok(); // can't test
 }
Esempio n. 16
0
  /** Provision a new slave for an EC2 spot instance to call back to Jenkins */
  private EC2AbstractSlave provisionSpot(TaskListener listener)
      throws AmazonClientException, IOException {
    PrintStream logger = listener.getLogger();
    AmazonEC2 ec2 = getParent().connect();

    try {
      logger.println("Launching " + ami + " for template " + description);
      LOGGER.info("Launching " + ami + " for template " + description);

      KeyPair keyPair = getKeyPair(ec2);

      RequestSpotInstancesRequest spotRequest = new RequestSpotInstancesRequest();

      // Validate spot bid before making the request
      if (getSpotMaxBidPrice() == null) {
        // throw new FormException("Invalid Spot price specified: " +
        // getSpotMaxBidPrice(), "spotMaxBidPrice");
        throw new AmazonClientException("Invalid Spot price specified: " + getSpotMaxBidPrice());
      }

      spotRequest.setSpotPrice(getSpotMaxBidPrice());
      spotRequest.setInstanceCount(1);

      LaunchSpecification launchSpecification = new LaunchSpecification();
      InstanceNetworkInterfaceSpecification net = new InstanceNetworkInterfaceSpecification();

      launchSpecification.setImageId(ami);
      launchSpecification.setInstanceType(type);

      if (StringUtils.isNotBlank(getZone())) {
        SpotPlacement placement = new SpotPlacement(getZone());
        launchSpecification.setPlacement(placement);
      }

      if (StringUtils.isNotBlank(getSubnetId())) {
        if (getAssociatePublicIp()) {
          net.setSubnetId(getSubnetId());
        } else {
          launchSpecification.setSubnetId(getSubnetId());
        }

        /*
         * If we have a subnet ID then we can only use VPC security groups
         */
        if (!securityGroupSet.isEmpty()) {
          List<String> groupIds = getEc2SecurityGroups(ec2);
          if (!groupIds.isEmpty()) {
            if (getAssociatePublicIp()) {
              net.setGroups(groupIds);
            } else {
              ArrayList<GroupIdentifier> groups = new ArrayList<GroupIdentifier>();

              for (String group_id : groupIds) {
                GroupIdentifier group = new GroupIdentifier();
                group.setGroupId(group_id);
                groups.add(group);
              }
              if (!groups.isEmpty()) launchSpecification.setAllSecurityGroups(groups);
            }
          }
        }
      } else {
        /* No subnet: we can use standard security groups by name */
        if (!securityGroupSet.isEmpty()) {
          launchSpecification.setSecurityGroups(securityGroupSet);
        }
      }

      String userDataString = Base64.encodeBase64String(userData.getBytes(StandardCharsets.UTF_8));

      launchSpecification.setUserData(userDataString);
      launchSpecification.setKeyName(keyPair.getKeyName());
      launchSpecification.setInstanceType(type.toString());

      if (getAssociatePublicIp()) {
        net.setAssociatePublicIpAddress(true);
        net.setDeviceIndex(0);
        launchSpecification.withNetworkInterfaces(net);
      }

      boolean hasCustomTypeTag = false;
      HashSet<Tag> instTags = null;
      if (tags != null && !tags.isEmpty()) {
        instTags = new HashSet<Tag>();
        for (EC2Tag t : tags) {
          instTags.add(new Tag(t.getName(), t.getValue()));
          if (StringUtils.equals(t.getName(), EC2Tag.TAG_NAME_JENKINS_SLAVE_TYPE)) {
            hasCustomTypeTag = true;
          }
        }
      }
      if (!hasCustomTypeTag) {
        if (instTags != null)
          instTags.add(
              new Tag(
                  EC2Tag.TAG_NAME_JENKINS_SLAVE_TYPE,
                  EC2Cloud.getSlaveTypeTagValue(EC2Cloud.EC2_SLAVE_TYPE_SPOT, description)));
      }

      if (StringUtils.isNotBlank(getIamInstanceProfile())) {
        launchSpecification.setIamInstanceProfile(
            new IamInstanceProfileSpecification().withArn(getIamInstanceProfile()));
      }

      if (useEphemeralDevices) {
        setupEphemeralDeviceMapping(launchSpecification);
      } else {
        setupCustomDeviceMapping(launchSpecification);
      }

      spotRequest.setLaunchSpecification(launchSpecification);

      // Make the request for a new Spot instance
      RequestSpotInstancesResult reqResult = ec2.requestSpotInstances(spotRequest);

      List<SpotInstanceRequest> reqInstances = reqResult.getSpotInstanceRequests();
      if (reqInstances.isEmpty()) {
        throw new AmazonClientException("No spot instances found");
      }

      SpotInstanceRequest spotInstReq = reqInstances.get(0);
      if (spotInstReq == null) {
        throw new AmazonClientException("Spot instance request is null");
      }
      String slaveName = spotInstReq.getSpotInstanceRequestId();

      /* Now that we have our Spot request, we can set tags on it */
      if (instTags != null) {
        updateRemoteTags(
            ec2,
            instTags,
            "InvalidSpotInstanceRequestID.NotFound",
            spotInstReq.getSpotInstanceRequestId());

        // That was a remote request - we should also update our local
        // instance data.
        spotInstReq.setTags(instTags);
      }

      logger.println("Spot instance id in provision: " + spotInstReq.getSpotInstanceRequestId());
      LOGGER.info("Spot instance id in provision: " + spotInstReq.getSpotInstanceRequestId());

      return newSpotSlave(spotInstReq, slaveName);

    } catch (FormException e) {
      throw new AssertionError(); // we should have discovered all
      // configuration issues upfront
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
  }
Esempio n. 17
0
  /**
   * Provisions an On-demand EC2 slave by launching a new instance or starting a previously-stopped
   * instance.
   */
  private EC2AbstractSlave provisionOndemand(
      TaskListener listener, Label requiredLabel, EnumSet<ProvisionOptions> provisionOptions)
      throws AmazonClientException, IOException {
    PrintStream logger = listener.getLogger();
    AmazonEC2 ec2 = getParent().connect();

    try {
      logProvisionInfo(logger, "Considering launching " + ami + " for template " + description);

      KeyPair keyPair = getKeyPair(ec2);

      RunInstancesRequest riRequest = new RunInstancesRequest(ami, 1, 1);
      InstanceNetworkInterfaceSpecification net = new InstanceNetworkInterfaceSpecification();

      riRequest.setEbsOptimized(ebsOptimized);

      if (useEphemeralDevices) {
        setupEphemeralDeviceMapping(riRequest);
      } else {
        setupCustomDeviceMapping(riRequest);
      }

      if (stopOnTerminate) {
        riRequest.setInstanceInitiatedShutdownBehavior(ShutdownBehavior.Stop);
        logProvisionInfo(
            logger, "Setting Instance Initiated Shutdown Behavior : ShutdownBehavior.Stop");
      } else {
        riRequest.setInstanceInitiatedShutdownBehavior(ShutdownBehavior.Terminate);
        logProvisionInfo(
            logger, "Setting Instance Initiated Shutdown Behavior : ShutdownBehavior.Terminate");
      }

      List<Filter> diFilters = new ArrayList<Filter>();
      diFilters.add(new Filter("image-id").withValues(ami));

      if (StringUtils.isNotBlank(getZone())) {
        Placement placement = new Placement(getZone());
        if (getUseDedicatedTenancy()) {
          placement.setTenancy("dedicated");
        }
        riRequest.setPlacement(placement);
        diFilters.add(new Filter("availability-zone").withValues(getZone()));
      }

      if (StringUtils.isNotBlank(getSubnetId())) {
        if (getAssociatePublicIp()) {
          net.setSubnetId(getSubnetId());
        } else {
          riRequest.setSubnetId(getSubnetId());
        }

        diFilters.add(new Filter("subnet-id").withValues(getSubnetId()));

        /*
         * If we have a subnet ID then we can only use VPC security groups
         */
        if (!securityGroupSet.isEmpty()) {
          List<String> groupIds = getEc2SecurityGroups(ec2);

          if (!groupIds.isEmpty()) {
            if (getAssociatePublicIp()) {
              net.setGroups(groupIds);
            } else {
              riRequest.setSecurityGroupIds(groupIds);
            }

            diFilters.add(new Filter("instance.group-id").withValues(groupIds));
          }
        }
      } else {
        /* No subnet: we can use standard security groups by name */
        riRequest.setSecurityGroups(securityGroupSet);
        if (!securityGroupSet.isEmpty()) {
          diFilters.add(new Filter("instance.group-name").withValues(securityGroupSet));
        }
      }

      String userDataString = Base64.encodeBase64String(userData.getBytes(StandardCharsets.UTF_8));
      riRequest.setUserData(userDataString);
      riRequest.setKeyName(keyPair.getKeyName());
      diFilters.add(new Filter("key-name").withValues(keyPair.getKeyName()));
      riRequest.setInstanceType(type.toString());
      diFilters.add(new Filter("instance-type").withValues(type.toString()));

      if (getAssociatePublicIp()) {
        net.setAssociatePublicIpAddress(true);
        net.setDeviceIndex(0);
        riRequest.withNetworkInterfaces(net);
      }

      boolean hasCustomTypeTag = false;
      HashSet<Tag> instTags = null;
      if (tags != null && !tags.isEmpty()) {
        instTags = new HashSet<Tag>();
        for (EC2Tag t : tags) {
          instTags.add(new Tag(t.getName(), t.getValue()));
          diFilters.add(new Filter("tag:" + t.getName()).withValues(t.getValue()));
          if (StringUtils.equals(t.getName(), EC2Tag.TAG_NAME_JENKINS_SLAVE_TYPE)) {
            hasCustomTypeTag = true;
          }
        }
      }
      if (!hasCustomTypeTag) {
        if (instTags == null) {
          instTags = new HashSet<Tag>();
        }
        // Append template description as well to identify slaves provisioned per template
        instTags.add(
            new Tag(
                EC2Tag.TAG_NAME_JENKINS_SLAVE_TYPE,
                EC2Cloud.getSlaveTypeTagValue(EC2Cloud.EC2_SLAVE_TYPE_DEMAND, description)));
      }

      DescribeInstancesRequest diRequest = new DescribeInstancesRequest();
      diRequest.setFilters(diFilters);

      logProvision(logger, "Looking for existing instances with describe-instance: " + diRequest);

      DescribeInstancesResult diResult = ec2.describeInstances(diRequest);
      EC2AbstractSlave[] ec2Node = new EC2AbstractSlave[1];
      Instance existingInstance = null;
      if (!provisionOptions.contains(ProvisionOptions.FORCE_CREATE)) {
        reservationLoop:
        for (Reservation reservation : diResult.getReservations()) {
          for (Instance instance : reservation.getInstances()) {
            if (checkInstance(logger, instance, requiredLabel, ec2Node)) {
              existingInstance = instance;
              logProvision(
                  logger,
                  "Found existing instance: "
                      + existingInstance
                      + ((ec2Node[0] != null) ? (" node: " + ec2Node[0].getInstanceId()) : ""));
              break reservationLoop;
            }
          }
        }
      }

      if (existingInstance == null) {
        if (!provisionOptions.contains(ProvisionOptions.FORCE_CREATE)
            && !provisionOptions.contains(ProvisionOptions.ALLOW_CREATE)) {
          logProvision(logger, "No existing instance found - but cannot create new instance");
          return null;
        }
        if (StringUtils.isNotBlank(getIamInstanceProfile())) {
          riRequest.setIamInstanceProfile(
              new IamInstanceProfileSpecification().withArn(getIamInstanceProfile()));
        }
        // Have to create a new instance
        Instance inst = ec2.runInstances(riRequest).getReservation().getInstances().get(0);

        /* Now that we have our instance, we can set tags on it */
        if (instTags != null) {
          updateRemoteTags(ec2, instTags, "InvalidInstanceID.NotFound", inst.getInstanceId());

          // That was a remote request - we should also update our
          // local instance data.
          inst.setTags(instTags);
        }
        logProvisionInfo(logger, "No existing instance found - created new instance: " + inst);
        return newOndemandSlave(inst);
      }

      if (existingInstance
              .getState()
              .getName()
              .equalsIgnoreCase(InstanceStateName.Stopping.toString())
          || existingInstance
              .getState()
              .getName()
              .equalsIgnoreCase(InstanceStateName.Stopped.toString())) {

        List<String> instances = new ArrayList<String>();
        instances.add(existingInstance.getInstanceId());
        StartInstancesRequest siRequest = new StartInstancesRequest(instances);
        StartInstancesResult siResult = ec2.startInstances(siRequest);

        logProvisionInfo(
            logger,
            "Found stopped instance - starting it: " + existingInstance + " result:" + siResult);
      } else {
        // Should be pending or running at this point, just let it come up
        logProvisionInfo(
            logger,
            "Found existing pending or running: "
                + existingInstance.getState().getName()
                + " instance: "
                + existingInstance);
      }

      if (ec2Node[0] != null) {
        logProvisionInfo(logger, "Using existing slave: " + ec2Node[0].getInstanceId());
        return ec2Node[0];
      }

      // Existing slave not found
      logProvision(logger, "Creating new slave for existing instance: " + existingInstance);
      return newOndemandSlave(existingInstance);

    } catch (FormException e) {
      throw new AssertionError(e); // we should have discovered all
      // configuration issues upfront
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }
  }