public MesosSlaveInfo getMesosSlaveInfoForLabel(Label label) {
    if (!matchesLabel(label)) {
      return null;
    }

    if (label == null) {
      if (getLabelString() == null) {
        return this;
      } else {
        return null;
      }
    }

    if (label.matches(Label.parse(getLabelString()))) {
      return this;
    }

    if (!containerInfo.getDockerImageCustomizable()) {
      return null;
    }

    String customImage = getCustomImage(label);
    if (customImage == null) {
      return null;
    }

    return copyWithDockerImage(label.toString(), customImage);
  }
 /** Returns slave template associated with the label */
 public AzureSlaveTemplate getAzureSlaveTemplate(Label label) {
   for (AzureSlaveTemplate slaveTemplate : instTemplates) {
     if (slaveTemplate.getUseSlaveAlwaysIfAvail() == Node.Mode.NORMAL) {
       if (label == null || label.matches(slaveTemplate.getLabelDataSet())) {
         return slaveTemplate;
       }
     } else if (slaveTemplate.getUseSlaveAlwaysIfAvail() == Node.Mode.EXCLUSIVE) {
       if (label != null && label.matches(slaveTemplate.getLabelDataSet())) {
         return slaveTemplate;
       }
     }
   }
   return null;
 }
示例#3
0
 /** Gets {@link SlaveTemplate} that has the matching {@link Label}. */
 public SlaveTemplate getTemplate(Label label) {
   for (SlaveTemplate t : templates) {
     if (t.getMode() == Node.Mode.NORMAL) {
       if (label == null || label.matches(t.getLabelSet())) {
         return t;
       }
     } else if (t.getMode() == Node.Mode.EXCLUSIVE) {
       if (label != null && label.matches(t.getLabelSet())) {
         return t;
       }
     }
   }
   return null;
 }
 @Issue("JENKINS-26123")
 @Test
 public void noWait() throws Exception {
   j.createFreeStyleProject("ds").setAssignedLabel(Label.get("nonexistent"));
   WorkflowJob us = j.jenkins.createProject(WorkflowJob.class, "us");
   us.setDefinition(new CpsFlowDefinition("build job: 'ds', wait: false"));
   j.assertBuildStatusSuccess(us.scheduleBuild2(0));
 }
示例#5
0
 private ECSTaskTemplate getTemplate(Label label) {
   for (ECSTaskTemplate t : templates) {
     if (label == null || label.matches(t.getLabelSet())) {
       return t;
     }
   }
   return null;
 }
  /**
   * Check if the label in the slave matches the provided label, either both are null or are the
   * same.
   *
   * @param label
   * @return Whether the slave label matches.
   */
  public boolean matchesLabel(@CheckForNull Label label) {

    if (label == null || getLabelString() == null) {
      return label == null && getLabelString() == null;
    }

    if (label.matches(Label.parse(getLabelString()))) {
      return true;
    }

    if (containerInfo == null || !containerInfo.getDockerImageCustomizable()) {
      return false;
    }

    String customImage = getCustomImage(label);
    return customImage != null
        && getLabelWithoutCustomImage(label, customImage).matches(Label.parse(getLabelString()));
  }
  private static String getCustomImage(Label label) {
    Matcher m = CUSTOM_IMAGE_FROM_LABEL_PATTERN.matcher(label.toString());

    if (m.find()) {
      return m.group(1);
    }

    return null;
  }
示例#8
0
  /**
   * Determines whether the AMI of the given instance matches the AMI of template and has the
   * required label (if requiredLabel is non-null)
   */
  private boolean checkInstance(
      PrintStream logger,
      Instance existingInstance,
      Label requiredLabel,
      EC2AbstractSlave[] returnNode) {
    logProvision(logger, "checkInstance: " + existingInstance);
    if (StringUtils.isNotBlank(getIamInstanceProfile())) {
      if (existingInstance.getIamInstanceProfile() != null) {
        if (!existingInstance.getIamInstanceProfile().getArn().equals(getIamInstanceProfile())) {
          logProvision(logger, " false - IAM Instance profile does not match");
          return false;
        }
        // Match, fall through
      } else {
        logProvision(logger, " false - Null IAM Instance profile");
        return false;
      }
    }

    if (existingInstance
            .getState()
            .getName()
            .equalsIgnoreCase(InstanceStateName.Terminated.toString())
        || existingInstance
            .getState()
            .getName()
            .equalsIgnoreCase(InstanceStateName.ShuttingDown.toString())) {
      logProvision(logger, " false - Instance is terminated or shutting down");
      return false;
    }
    // See if we know about this and it has capacity
    for (EC2AbstractSlave node : NodeIterator.nodes(EC2AbstractSlave.class)) {
      if (node.getInstanceId().equals(existingInstance.getInstanceId())) {
        logProvision(logger, "Found existing corresponding Jenkins slave: " + node.getInstanceId());
        if (!node.toComputer().isPartiallyIdle()) {
          logProvision(logger, " false - Node is not partially idle");
          return false;
        }
        // REMOVEME - this was added to force provision to work, but might not allow
        // stopped instances to be found - need to investigate further
        else if (false && node.toComputer().isOffline()) {
          logProvision(logger, " false - Node is offline");
          return false;
        } else if (requiredLabel != null && !requiredLabel.matches(node.getAssignedLabels())) {
          logProvision(logger, " false - we need a Node having label " + requiredLabel);
          return false;
        } else {
          logProvision(logger, " true - Node has capacity - can use it");
          returnNode[0] = node;
          return true;
        }
      }
    }
    logProvision(logger, " true - Instance has no node, but can be used");
    return true;
  }
 public EcsTaskTemplate getTemplate(Label label) {
   if (label == null && templates.size() > 0) {
     return templates.get(0);
   }
   for (EcsTaskTemplate t : templates) {
     if (label.matches(t.getLabelSet())) {
       return t;
     }
   }
   return null;
 }
  @Test
  public void testLabelExpression() throws Exception {
    setUpCloud(LABEL1 + " " + LABEL2);

    assertEquals(true, ac.canProvision(Label.parseExpression(LABEL1 + " || " + LABEL2)));
    assertEquals(true, ac.canProvision(Label.parseExpression(LABEL1 + " && " + LABEL2)));
    assertEquals(true, ac.canProvision(Label.parseExpression(LABEL1 + " || aaa")));
    assertEquals(false, ac.canProvision(Label.parseExpression(LABEL1 + " && aaa")));
    assertEquals(false, ac.canProvision(Label.parseExpression("aaa || bbb")));
    assertEquals(false, ac.canProvision(Label.parseExpression("aaa || bbb")));
  }
示例#11
0
  /** Initializes data structure that we don't persist. */
  public Object readResolve() {
    if (configVersion < 1) {
      try {
        convert1();
      } catch (Throwable t) {
        LOGGER.log(Level.SEVERE, "Can't convert old values to new (double conversion?): ", t);
      }

      configVersion = 1;
    }

    try {
      labelSet = Label.parse(labelString); // fails sometimes under debugger
    } catch (Throwable t) {
      LOGGER.log(Level.SEVERE, "Can't parse labels: ", t);
    }

    return this;
  }
示例#12
0
  @DataBoundConstructor
  public DockerTemplate(
      DockerTemplateBase dockerTemplateBase,
      String labelString,
      String remoteFs,
      String remoteFsMapping,
      String instanceCapStr) {
    this.dockerTemplateBase = dockerTemplateBase;
    this.labelString = Util.fixNull(labelString);
    this.remoteFs = Strings.isNullOrEmpty(remoteFs) ? "/home/jenkins" : remoteFs;
    this.remoteFsMapping = remoteFsMapping;

    if (instanceCapStr.equals("")) {
      this.instanceCap = Integer.MAX_VALUE;
    } else {
      this.instanceCap = Integer.parseInt(instanceCapStr);
    }

    labelSet = Label.parse(labelString);
  }
示例#13
0
  /** Initializes data structure that we don't persist. */
  protected Object readResolve() {
    labelSet = Label.parse(labels);
    securityGroupSet = parseSecurityGroups();

    /**
     * In releases of this plugin prior to 1.18, template-specific instance caps could be configured
     * but were not enforced. As a result, it was possible to have the instance cap for a template
     * be configured to 0 (zero) with no ill effects. Starting with version 1.18, template-specific
     * instance caps are enforced, so if a configuration has a cap of zero for a template, no
     * instances will be launched from that template. Since there is no practical value of
     * intentionally setting the cap to zero, this block will override such a setting to a value
     * that means 'no cap'.
     */
    if (instanceCap == 0) {
      instanceCap = Integer.MAX_VALUE;
    }

    if (amiType == null) {
      amiType = new UnixData(rootCommandPrefix, sshPort);
    }
    return this;
  }
示例#14
0
  public boolean canProvision(Label label) {
    AzureSlaveTemplate template = getAzureSlaveTemplate(label);

    // return false if there is no template
    if (template == null) {
      if (label != null) {
        LOGGER.info(
            "Azurecloud: canProvision: template not found for label " + label.getDisplayName());
      } else {
        LOGGER.info(
            "Azurecloud: canProvision: template not found for empty label.	All templates exclusive to jobs that require that template.");
      }
      return false;
    } else if (template.getTemplateStatus().equalsIgnoreCase(Constants.TEMPLATE_STATUS_DISBALED)) {
      LOGGER.info(
          "Azurecloud: canProvision: template "
              + template.getTemplateName()
              + " is marked has disabled, cannot provision slaves");
      return false;
    } else {
      return true;
    }
  }
示例#15
0
  @Override
  public Collection<PlannedNode> provision(Label label, int excessWorkload) {
    try {
      // Count number of pending executors from spot requests
      for (EC2SpotSlave n : NodeIterator.nodes(EC2SpotSlave.class)) {
        // If the slave is online then it is already counted by Jenkins
        // We only want to count potential additional Spot instance
        // slaves
        if (n.getComputer().isOffline() && label.matches(n.getAssignedLabels())) {
          DescribeSpotInstanceRequestsRequest dsir =
              new DescribeSpotInstanceRequestsRequest()
                  .withSpotInstanceRequestIds(n.getSpotInstanceRequestId());

          for (SpotInstanceRequest sir :
              connect().describeSpotInstanceRequests(dsir).getSpotInstanceRequests()) {
            // Count Spot requests that are open and still have a
            // chance to be active
            // A request can be active and not yet registered as a
            // slave. We check above
            // to ensure only unregistered slaves get counted
            if (sir.getState().equals("open") || sir.getState().equals("active")) {
              excessWorkload -= n.getNumExecutors();
            }
          }
        }
      }
      LOGGER.log(Level.INFO, "Excess workload after pending Spot instances: " + excessWorkload);

      List<PlannedNode> r = new ArrayList<PlannedNode>();

      final SlaveTemplate t = getTemplate(label);
      int amiCap = t.getInstanceCap();

      while (excessWorkload > 0) {

        if (!addProvisionedSlave(t.ami, amiCap, t.description)) {
          break;
        }

        r.add(
            new PlannedNode(
                t.getDisplayName(),
                Computer.threadPoolForRemoting.submit(
                    new Callable<Node>() {
                      public Node call() throws Exception {
                        // TODO: record the output somewhere
                        try {
                          EC2AbstractSlave s = t.provision(StreamTaskListener.fromStdout());
                          Hudson.getInstance().addNode(s);
                          // EC2 instances may have a long init script. If we
                          // declare
                          // the provisioning complete by returning without
                          // the connect
                          // operation, NodeProvisioner may decide that it
                          // still wants
                          // one more instance, because it sees that (1) all
                          // the slaves
                          // are offline (because it's still being launched)
                          // and
                          // (2) there's no capacity provisioned yet.
                          //
                          // deferring the completion of provisioning until
                          // the launch
                          // goes successful prevents this problem.
                          s.toComputer().connect(false).get();
                          return s;
                        } finally {
                          decrementAmiSlaveProvision(t.ami);
                        }
                      }
                    }),
                t.getNumExecutors()));

        excessWorkload -= t.getNumExecutors();
      }
      return r;
    } catch (AmazonClientException e) {
      LOGGER.log(Level.WARNING, "Failed to count the # of live instances on EC2", e);
      return Collections.emptyList();
    }
  }
 @Override
 public Label getAssignedLabel(SubTask task) {
   return Label.get(label);
 }
 /**
  * Initializes data structure that we don't persist.
  */
 protected Object readResolve() {
     labelSet = Label.parse(labelString);
     return this;
 }
示例#18
0
    public Node call() throws Exception {

      String uniq = Long.toHexString(System.nanoTime());
      ECSSlave slave =
          new ECSSlave(
              ECSCloud.this,
              name + "-" + uniq,
              template.getRemoteFSRoot(),
              label == null ? null : label.toString(),
              new JNLPLauncher());
      Jenkins.getInstance().addNode(slave);
      LOGGER.log(Level.INFO, "Created Slave: {0}", slave.getNodeName());

      final AmazonECSClient client = getAmazonECSClient();
      LOGGER.log(Level.INFO, "Selected Region: {0}", getRegionName());
      client.setRegion(getRegion(getRegionName()));

      Collection<String> command = getDockerRunCommand(slave);
      String definitionArn = template.getTaskDefinitionArn();
      slave.setTaskDefinitonArn(definitionArn);

      final RunTaskResult runTaskResult =
          client.runTask(
              new RunTaskRequest()
                  .withTaskDefinition(definitionArn)
                  .withOverrides(
                      new TaskOverride()
                          .withContainerOverrides(
                              new ContainerOverride()
                                  .withName("jenkins-slave")
                                  .withCommand(command)))
                  .withCluster(cluster));

      if (!runTaskResult.getFailures().isEmpty()) {
        LOGGER.log(
            Level.WARNING,
            "Slave {0} - Failure to run task with definition {1} on ECS cluster {2}",
            new Object[] {slave.getNodeName(), definitionArn, cluster});
        for (Failure failure : runTaskResult.getFailures()) {
          LOGGER.log(
              Level.WARNING,
              "Slave {0} - Failure reason={1}, arn={2}",
              new Object[] {slave.getNodeName(), failure.getReason(), failure.getArn()});
        }
        throw new AbortException("Failed to run slave container " + slave.getNodeName());
      }

      String taskArn = runTaskResult.getTasks().get(0).getTaskArn();
      LOGGER.log(
          Level.INFO,
          "Slave {0} - Slave Task Started : {1}",
          new Object[] {slave.getNodeName(), taskArn});
      slave.setTaskArn(taskArn);

      int i = 0;
      int j = 100; // wait 100 seconds

      // now wait for slave to be online
      for (; i < j; i++) {
        if (slave.getComputer() == null) {
          throw new IllegalStateException(
              "Slave " + slave.getNodeName() + " - Node was deleted, computer is null");
        }
        if (slave.getComputer().isOnline()) {
          break;
        }
        LOGGER.log(
            Level.FINE,
            "Waiting for slave {0} (ecs task {1}) to connect ({2}/{3}).",
            new Object[] {slave.getNodeName(), taskArn, i, j});
        Thread.sleep(1000);
      }
      if (!slave.getComputer().isOnline()) {
        throw new IllegalStateException(
            "ECS Slave "
                + slave.getNodeName()
                + " (ecs task "
                + taskArn
                + ") is not connected after "
                + j
                + " seconds");
      }

      LOGGER.log(
          Level.INFO, "ECS Slave " + slave.getNodeName() + " (ecs task {0}) connected", taskArn);
      return slave;
    }
 private static Label getLabelWithoutCustomImage(Label label, String customDockerImage) {
   return Label.get(label.toString().replace(CUSTOM_IMAGE_SEPARATOR + customDockerImage, ""));
 }
  public static void startSeleniumNode(Computer c, TaskListener listener, String conf)
      throws IOException, InterruptedException {
    LOGGER.fine("Examining if we need to start Selenium Grid Node");

    final PluginImpl p = Hudson.getInstance().getPlugin(PluginImpl.class);

    final String exclusions = p.getExclusionPatterns();
    List<String> exclusionPatterns = new ArrayList<String>();
    if (StringUtils.hasText(exclusions)) {
      exclusionPatterns = Arrays.asList(exclusions.split(SEPARATOR));
    }
    if (exclusionPatterns.size() > 0) {
      // loop over all the labels and check if we need to exclude a node
      // based on the exlusionPatterns
      for (Label label : c.getNode().getAssignedLabels()) {
        for (String pattern : exclusionPatterns) {
          if (label.toString().matches(pattern)) {
            LOGGER.fine(
                "Node "
                    + c.getNode().getDisplayName()
                    + " is excluded from Selenium Grid because its label '"
                    + label
                    + "' matches exclusion pattern '"
                    + pattern
                    + "'");
            return;
          }
        }
      }
    }

    final String masterName = PluginImpl.getMasterHostName();
    if (masterName == null) {
      listener
          .getLogger()
          .println(
              "Unable to determine the host name of the master. Skipping Selenium execution. "
                  + "Please "
                  + HyperlinkNote.encodeTo("/configure", "configure the Jenkins URL")
                  + " from the system configuration screen.");
      return;
    }

    // make sure that Selenium Hub is started before we start RCs.
    try {
      p.waitForHubLaunch();
    } catch (ExecutionException e) {
      throw new IOException2("Failed to wait for the Hub launch to complete", e);
    }

    List<SeleniumGlobalConfiguration> confs = getPlugin().getGlobalConfigurationForComputer(c);
    if (confs == null || confs.size() == 0) {
      LOGGER.fine(
          "There is no matching configurations for that computer. Skipping selenium execution.");
      return;
    }

    String nodehost = c.getHostName();
    if (nodehost == null) {
      LOGGER.warning("Unable to determine node's hostname. Skipping");
      return;
    }

    listener
        .getLogger()
        .println(
            "Starting Selenium nodes on " + ("".equals(c.getName()) ? "(master)" : c.getName()));

    for (SeleniumGlobalConfiguration config : confs) {
      if ((conf != null && config.getName().equals(conf)) || conf == null) {
        try {
          config.start(c, listener);
        } catch (ExecutionException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }
  }
示例#21
0
 public String getShortDescription() {
   return Messages.Queue_WaitingForNextAvailableExecutorOn(label.getName());
 }
 public void testQuote() {
   Label l = jenkins.getLabel("\"abc\\\\\\\"def\"");
   assertEquals("abc\\\"def", l.getName());
 }
示例#23
0
 public String getShortDescription() {
   return Messages.Queue_AllNodesOffline(label.getName());
 }