Beispiel #1
0
  public synchronized TopLevelItem createProjectFromXML(String name, InputStream xml)
      throws IOException {
    acl.checkPermission(Job.CREATE);

    Jenkins.getInstance().getProjectNamingStrategy().checkName(name);
    // place it as config.xml
    File configXml = Items.getConfigFile(getRootDirFor(name)).getFile();
    configXml.getParentFile().mkdirs();
    try {
      IOUtils.copy(xml, configXml);

      // load it
      TopLevelItem result;
      Items.updatingByXml.set(true);
      try {
        result = (TopLevelItem) Items.load(parent, configXml.getParentFile());
      } finally {
        Items.updatingByXml.set(false);
      }
      add(result);

      ItemListener.fireOnCreated(result);
      Jenkins.getInstance().rebuildDependencyGraph();

      return result;
    } catch (IOException e) {
      // if anything fails, delete the config file to avoid further confusion
      Util.deleteRecursive(configXml.getParentFile());
      throw e;
    }
  }
Beispiel #2
0
    /**
     * Updates Job by its XML definition.
     * @since 1.473
     */
    public void updateByXml(Source source) throws IOException {
        checkPermission(CONFIGURE);
        XmlFile configXmlFile = getConfigFile();
        AtomicFileWriter out = new AtomicFileWriter(configXmlFile.getFile());
        try {
            try {
                // this allows us to use UTF-8 for storing data,
                // plus it checks any well-formedness issue in the submitted
                // data
                Transformer t = TransformerFactory.newInstance()
                        .newTransformer();
                t.transform(source,
                        new StreamResult(out));
                out.close();
            } catch (TransformerException e) {
                throw new IOException("Failed to persist config.xml", e);
            }

            // try to reflect the changes by reloading
            new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshal(this);
            Items.whileUpdatingByXml(new Callable<Void,IOException>() {
                @Override public Void call() throws IOException {
                    onLoad(getParent(), getRootDir().getName());
                    return null;
                }
            });
            Jenkins.getInstance().rebuildDependencyGraphAsync();

            // if everything went well, commit this new version
            out.commit();
            SaveableListener.fireOnChange(this, getConfigFile());
        } finally {
            out.abort(); // don't leave anything behind
        }
    }
Beispiel #3
0
  /**
   * Creates a {@link TopLevelItem} from the submission of the '/lib/hudson/newFromList/formList' or
   * throws an exception if it fails.
   */
  public synchronized TopLevelItem createTopLevelItem(StaplerRequest req, StaplerResponse rsp)
      throws IOException, ServletException {
    acl.checkPermission(Job.CREATE);

    TopLevelItem result;

    String requestContentType = req.getContentType();
    if (requestContentType == null) throw new Failure("No Content-Type header set");

    boolean isXmlSubmission =
        requestContentType.startsWith("application/xml")
            || requestContentType.startsWith("text/xml");

    String name = req.getParameter("name");
    if (name == null) throw new Failure("Query parameter 'name' is required");

    { // check if the name looks good
      Jenkins.checkGoodName(name);
      name = name.trim();
      if (parent.getItem(name) != null) throw new Failure(Messages.Hudson_JobAlreadyExists(name));
    }

    String mode = req.getParameter("mode");
    if (mode != null && mode.equals("copy")) {
      String from = req.getParameter("from");

      // resolve a name to Item
      Item src = null;
      if (!from.startsWith("/")) src = parent.getItem(from);
      if (src == null) src = Jenkins.getInstance().getItemByFullName(from);

      if (src == null) {
        if (Util.fixEmpty(from) == null) throw new Failure("Specify which job to copy");
        else throw new Failure("No such job: " + from);
      }
      if (!(src instanceof TopLevelItem)) throw new Failure(from + " cannot be copied");

      result = copy((TopLevelItem) src, name);
    } else {
      if (isXmlSubmission) {
        result = createProjectFromXML(name, req.getInputStream());
        rsp.setStatus(HttpServletResponse.SC_OK);
        return result;
      } else {
        if (mode == null) throw new Failure("No mode given");

        // create empty job and redirect to the project config screen
        result = createProject(Items.all().findByName(mode), name, true);
      }
    }

    rsp.sendRedirect2(redirectAfterCreateItem(req, result));
    return result;
  }
Beispiel #4
0
  /**
   * Copies an existing {@link TopLevelItem} to a new name.
   *
   * <p>The caller is responsible for calling {@link ItemListener#fireOnCopied(Item, Item)}. This
   * method cannot do that because it doesn't know how to make the newly added item reachable from
   * the parent.
   */
  @SuppressWarnings({"unchecked"})
  public synchronized <T extends TopLevelItem> T copy(T src, String name) throws IOException {
    acl.checkPermission(Job.CREATE);

    T result = (T) createProject(src.getDescriptor(), name, false);

    // copy config
    Util.copyFile(Items.getConfigFile(src).getFile(), Items.getConfigFile(result).getFile());

    // reload from the new config
    Items.updatingByXml.set(true);
    try {
      result = (T) Items.load(parent, result.getRootDir());
    } finally {
      Items.updatingByXml.set(false);
    }
    result.onCopiedFrom(src);

    add(result);
    ItemListener.fireOnCopied(src, result);
    Hudson.getInstance().rebuildDependencyGraph();

    return result;
  }
  /** @param env Environment variables from which to expand project names; Might be {@code null}. */
  public List<AbstractProject> getProjectList(EnvVars env) {
    if (projectList == null) {
      projectList = new ArrayList<AbstractProject>();

      // expand variables if applicable
      StringBuilder projectNames = new StringBuilder();
      StringTokenizer tokens = new StringTokenizer(projects, ",");
      while (tokens.hasMoreTokens()) {
        if (projectNames.length() > 0) {
          projectNames.append(',');
        }
        projectNames.append(
            env != null ? env.expand(tokens.nextToken().trim()) : tokens.nextToken().trim());
      }

      projectList.addAll(Items.fromNameList(projectNames.toString(), AbstractProject.class));
    }
    return projectList;
  }
Beispiel #6
0
  public synchronized void checkPendingDownstream(
      AbstractBuild<?, ?> owner, TaskListener listener) {
    if (pendingDownstreamProjects.isEmpty()) {
      listener.getLogger().println("All downstream projects complete!");
      Result threshold = this.evenIfDownstreamUnstable ? Result.UNSTABLE : Result.SUCCESS;
      if (this.overallResult.isWorseThan(threshold)) {
        listener.getLogger().println("Minimum result threshold not met for join project");
      } else {
        // Construct a launcher since CopyArchiver wants to get the
        // channel from it. We use the channel of the node where the
        // splitProject was built on.
        final Launcher launcher = new NoopLauncher(listener, owner);

        for (Publisher pub : this.joinPublishers) {
          try {
            pub.perform(owner, launcher, (BuildListener) listener);
          } catch (InterruptedException e) {
            e.printStackTrace();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
        if (!JoinTrigger.canDeclare(owner.getProject())) {
          List<AbstractProject> projects = Items.fromNameList(joinProjects, AbstractProject.class);
          for (AbstractProject project : projects) {
            listener.getLogger().println("Scheduling join project: " + project.getName());
            project.scheduleBuild(new JoinCause(owner));
          }
        }
      }
    } else {
      listener
          .getLogger()
          .println(
              "Project "
                  + owner.getProject().getName()
                  + " still waiting for "
                  + pendingDownstreamProjects.size()
                  + " builds to complete");
    }
  }
  private void updateGeneratedJobMap(
      AbstractProject<?, ?> seedJob,
      Set<GeneratedJob> createdOrUpdatedJobs,
      Set<GeneratedJob> removedJobs)
      throws IOException {
    DescriptorImpl descriptor = Jenkins.getInstance().getDescriptorByType(DescriptorImpl.class);
    boolean descriptorMutated = false;
    Map<String, SeedReference> generatedJobMap = descriptor.getGeneratedJobMap();

    for (GeneratedJob generatedJob : createdOrUpdatedJobs) {
      Item item = getLookupStrategy().getItem(seedJob, generatedJob.getJobName(), Item.class);
      if (item != null) {
        SeedReference newSeedReference = new SeedReference(seedJob.getFullName());
        if (generatedJob.getTemplateName() != null) {
          Item template =
              getLookupStrategy().getItem(seedJob, generatedJob.getTemplateName(), Item.class);
          newSeedReference.setTemplateJobName(template.getFullName());
        }
        newSeedReference.setDigest(Util.getDigestOf(Items.getConfigFile(item).getFile()));

        SeedReference oldSeedReference = generatedJobMap.get(item.getFullName());
        if (!newSeedReference.equals(oldSeedReference)) {
          generatedJobMap.put(item.getFullName(), newSeedReference);
          descriptorMutated = true;
        }
      }
    }

    for (GeneratedJob removedJob : removedJobs) {
      Item removedItem = getLookupStrategy().getItem(seedJob, removedJob.getJobName(), Item.class);
      if (removedItem != null) {
        generatedJobMap.remove(removedItem.getFullName());
        descriptorMutated = true;
      }
    }

    if (descriptorMutated) {
      descriptor.save();
    }
  }
Beispiel #8
0
  /**
   * Loads all the child {@link Item}s.
   *
   * @param modulesDir Directory that contains sub-directories for each child item.
   */
  public static <K, V extends Item> Map<K, V> loadChildren(
      ItemGroup parent, File modulesDir, Function1<? extends K, ? super V> key) {
    modulesDir.mkdirs(); // make sure it exists

    File[] subdirs =
        modulesDir.listFiles(
            new FileFilter() {
              public boolean accept(File child) {
                return child.isDirectory();
              }
            });
    CopyOnWriteMap.Tree<K, V> configurations = new CopyOnWriteMap.Tree<K, V>();
    for (File subdir : subdirs) {
      try {
        V item = (V) Items.load(parent, subdir);
        configurations.put(key.call(item), item);
      } catch (IOException e) {
        e.printStackTrace(); // TODO: logging
      }
    }

    return configurations;
  }
Beispiel #9
0
  /** Gets the encrypted usage stat data to be sent to the Hudson server. */
  public String getStatData() throws IOException {
    Jenkins j = Jenkins.getInstance();

    JSONObject o = new JSONObject();
    o.put("stat", 1);
    o.put("install", j.getLegacyInstanceId());
    o.put("servletContainer", j.servletContext.getServerInfo());
    o.put("version", Jenkins.VERSION);

    List<JSONObject> nodes = new ArrayList<JSONObject>();
    for (Computer c : j.getComputers()) {
      JSONObject n = new JSONObject();
      if (c.getNode() == j) {
        n.put("master", true);
        n.put("jvm-vendor", System.getProperty("java.vm.vendor"));
        n.put("jvm-name", System.getProperty("java.vm.name"));
        n.put("jvm-version", System.getProperty("java.version"));
      }
      n.put("executors", c.getNumExecutors());
      DescriptorImpl descriptor = j.getDescriptorByType(DescriptorImpl.class);
      n.put("os", descriptor.get(c));
      nodes.add(n);
    }
    o.put("nodes", nodes);

    List<JSONObject> plugins = new ArrayList<JSONObject>();
    for (PluginWrapper pw : j.getPluginManager().getPlugins()) {
      if (!pw.isActive()) continue; // treat disabled plugins as if they are uninstalled
      JSONObject p = new JSONObject();
      p.put("name", pw.getShortName());
      p.put("version", pw.getVersion());
      plugins.add(p);
    }
    o.put("plugins", plugins);

    JSONObject jobs = new JSONObject();
    List<TopLevelItem> items = j.getAllItems(TopLevelItem.class);
    for (TopLevelItemDescriptor d : Items.all()) {
      int cnt = 0;
      for (TopLevelItem item : items) {
        if (item.getDescriptor() == d) cnt++;
      }
      jobs.put(d.getJsonSafeClassName(), cnt);
    }
    o.put("jobs", jobs);

    try {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();

      // json -> UTF-8 encode -> gzip -> encrypt -> base64 -> string
      OutputStreamWriter w =
          new OutputStreamWriter(
              new GZIPOutputStream(new CombinedCipherOutputStream(baos, getKey(), "AES")), "UTF-8");
      try {
        o.write(w);
      } finally {
        IOUtils.closeQuietly(w);
      }

      return new String(Base64.encode(baos.toByteArray()));
    } catch (GeneralSecurityException e) {
      throw new Error(e); // impossible
    }
  }
 @SuppressWarnings("unchecked")
 private static <I extends AbstractItem & TopLevelItem> I doMove(
     Item item, DirectlyModifiableTopLevelItemGroup destination) throws IOException {
   return Items.move((I) item, destination);
 }
 public List<AbstractProject> getChildProjects() {
   return Items.fromNameList(childProjects, AbstractProject.class);
 }
 public List<AbstractProject> getProjectList() {
   return Items.fromNameList(projects, AbstractProject.class);
 }
Beispiel #13
0
 public final XmlFile getConfigFile() {
     return Items.getConfigFile(this);
 }
Beispiel #14
0
 public static String getProjectListString(List<Project> projects) {
   return Items.toNameList(projects);
 }