【问题标题】:Jenkins API throws IOException: Failed to persist config.xmlJenkins API 抛出 IOException:无法持久化 config.xml
【发布时间】:2018-04-04 01:26:40
【问题描述】:

我正在尝试使用带有 curl 的 Jenkins API 在 Ubuntu 17.10 上创建新作业。我正在关注this thread 上的示例。创建面包屑效果很好。但是,创建作业的调用失败并带有根本原因的堆栈跟踪:

[编辑以添加堆栈跟踪的其余部分]

org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Premature end of file.
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1239)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:668)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:737)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:351)
    at jenkins.util.xml.XMLUtils._transform(XMLUtils.java:212)
    at jenkins.util.xml.XMLUtils.safeTransform(XMLUtils.java:84)
    at hudson.model.ItemGroupMixIn.createProjectFromXML(ItemGroupMixIn.java:272)
    at hudson.model.ItemGroupMixIn.createTopLevelItem(ItemGroupMixIn.java:189)
    at jenkins.model.Jenkins.doCreateItem(Jenkins.java:3816)
    at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
    at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)
    at org.kohsuke.stapler.interceptor.RequirePOST$Processor.invoke(RequirePOST.java:77)
    at org.kohsuke.stapler.PreInvokeInterceptedFunction.invoke(PreInvokeInterceptedFunction.java:26)
    at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184)
    at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:117)
    at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:129)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at jenkins.security.ApiCrumbExclusion.process(ApiCrumbExclusion.java:48)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:73)
    ...
Caused: java.io.IOException: Failed to persist config.xml
    at hudson.model.ItemGroupMixIn.createProjectFromXML(ItemGroupMixIn.java:292)
    at hudson.model.ItemGroupMixIn.createTopLevelItem(ItemGroupMixIn.java:189)
    at jenkins.model.Jenkins.doCreateItem(Jenkins.java:3816)
    at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
    at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:343)
    at org.kohsuke.stapler.interceptor.RequirePOST$Processor.invoke(RequirePOST.java:77)
    at org.kohsuke.stapler.PreInvokeInterceptedFunction.invoke(PreInvokeInterceptedFunction.java:26)
    at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:184)
    at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:117)
    at org.kohsuke.stapler.MetaClass$1.doDispatch(MetaClass.java:129)
    at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:58)
    at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:715)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:845)
    at org.kohsuke.stapler.Stapler.invoke(Stapler.java:649)
    at org.kohsuke.stapler.Stapler.service(Stapler.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1650)
    at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:154)
    at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:157)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at jenkins.security.ApiCrumbExclusion.process(ApiCrumbExclusion.java:48)
    at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:73)
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1637)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:84)
    at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:51)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at jenkins.security.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:117)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:125)
    at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:87)
    ...

脚本文件是:

CRUMB=$(curl -s 'http://<redacted>@localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')

echo ${CRUMB}

curl -X POST -H "$CRUMB" -H "content-type:application/xml" "http://<redacted>@localhost:8080/createItem?name=NewJob2"

[编辑]

也尝试过这种变体,尝试传递一个基本的 config.xml 文件:

curl -X POST -H "$CRUMB" -H "content-type:application/xml" --data "@config.xml" "http://helo478:5ccf2750debe105962b1bf3a8483cfd8@localhost:8080/createItem?name=Test" --trace-ascii /dev/stdout

【问题讨论】:

  • 詹金斯对文件夹有写权限吗?
  • 必须的,对吧?我可以使用 GUI 毫无问题地做同样的事情。
  • 是的,确实如此。 drwxr-xr-x 15 jenkins jenkins 4096 Apr 3 17:33 jenkins-rw-r--r-- 1 jenkins jenkins 1825 Apr 3 17:33 config.xml
  • 我还尝试将为其创建 crumb 的用户添加到 jenkins 组。还是一样的错误
  • 看起来你还没有发布整个堆栈跟踪,第一个喜欢说caused...,这表明还有其他原因导致了这个。如果可能的话,如果我们可以查看您尝试上传的配置也会有所帮助。

标签: jenkins jenkins-api


【解决方案1】:

只是发布一个我作为评论记录的答案。看起来整个堆栈跟踪都丢失了,第一行显示为caused...,这表明还有更多异常。

此外,我查看了第一个堆栈跟踪帧的来源, hudson.model.ItemGroupMixIn.createProjectFromXML line 292,从那里很明显上传的 XML 文件有问题,显然根本没有上传。

来自 Jenkins API 文档,地址为 &lt;jenkins instance root&gt;/api/

要创建新作业,请使用查询参数 name=JOBNAME 将 config.xml 发布到此 URL。您需要发送一个 Content-Type: application/xml 标头。如果创建成功,您将获得 200 状态码,如果创建失败,您将获得 4xx/5xx 码。 config.xml 是 Jenkins 用于将项目存储在文件系统中的格式,因此您可以在 Jenkins 主目录中查看它们的示例,或者通过从 /job/JOBNAME/config.xml 检索现有作业的 XML 配置。

【讨论】:

    【解决方案2】:

    API 要求在发布数据中传递 config.xml 文件。我曾假设,就像 GUI 一样,它会自动创建一个基本的。不是这样的

    curl -X POST -H "$CRUMB" -H "content-type:application/xml" --data "@/home/helo478/Documents/config.xml" "http://helo478:5ccf2750debe105962b1bf3a8483cfd8@localhost:8080/createItem?name=Test5" --trace-ascii /dev/stdout
    

    config.xml:

    <?xml version='1.1' encoding='UTF-8'?>
    <org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="workflow-multibranch@2.17">
      <actions/>
      <description></description>
      <displayName>Test5</displayName>
      <properties>
        <org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig plugin="pipeline-model-definition@1.2.7">
          <dockerLabel></dockerLabel>
          <registry plugin="docker-commons@1.11"/>
        </org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig>
      </properties>
      <folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="branch-api@2.0.18">
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
      </folderViews>
      <healthMetrics>
        <com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric plugin="cloudbees-folder@6.4">
          <nonRecursive>false</nonRecursive>
        </com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
      </healthMetrics>
      <icon class="jenkins.branch.MetadataActionFolderIcon" plugin="branch-api@2.0.18">
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
      </icon>
      <orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="cloudbees-folder@6.4">
        <pruneDeadBranches>true</pruneDeadBranches>
        <daysToKeep>-1</daysToKeep>
        <numToKeep>-1</numToKeep>
      </orphanedItemStrategy>
      <triggers/>
      <disabled>false</disabled>
      <sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="branch-api@2.0.18">
        <data>
          <jenkins.branch.BranchSource>
            <source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="github-branch-source@2.3.3">
              <id>e514c038-dfd3-4748-99f1-8eb807276814</id>
              <credentialsId>54956458-e73d-45db-8ed1-04cb42a3612e</credentialsId>
              <repoOwner>helo478</repoOwner>
              <repository>agartha-web</repository>
              <traits>
                <org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
                  <strategyId>1</strategyId>
                </org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
                <org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
                  <strategyId>1</strategyId>
                </org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
                <org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
                  <strategyId>1</strategyId>
                  <trust class="org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$TrustPermission"/>
                </org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
              </traits>
            </source>
            <strategy class="jenkins.branch.DefaultBranchPropertyStrategy">
              <properties class="empty-list"/>
            </strategy>
          </jenkins.branch.BranchSource>
        </data>
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
      </sources>
      <factory class="org.jenkinsci.plugins.workflow.multibranch.WorkflowBranchProjectFactory">
        <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
        <scriptPath>Jenkinsfile</scriptPath>
      </factory>
    </org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject>
    

    【讨论】:

      猜你喜欢
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多