Jenkins API бросает IOException: не удалось сохранить config.xml

Я пытаюсь использовать Jenkins API с curl для создания новой работы на Ubuntu 17.10. Я следую примеру этого потока. Создание крошки хорошо работает. Однако вызов для создания задания завершается неудачей с трассировкой стека с основной причиной:

[отредактировано, чтобы добавить остальную трассировку стека]

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:[email protected]:8080/createItem?name=Test" --trace-ascii /dev/stdout

Ответ 1

Просто отправьте ответ с тем, что я отметил как комментарий. Похоже, что вся трассировка стека отсутствовала, первая строка была caused... что указывает на то, что существует больше исключения.

Кроме того, я взглянул на источник первого кадра трассировки трассировки hudson.model.ItemGroupMixIn.createProjectFromXML строки 292, оттуда он довольно очевидно, что что-то не так с загруженным XML файлом, который, по-видимому, не был загружен вообще,

Из документации Jenkins API, доступной в <jenkins instance root>/api/:

Чтобы создать новое задание, отправьте config.xml на этот URL-адрес с параметром запроса = JOBNAME. Вам необходимо отправить заголовок Content-Type: application/xml. Вы получите код статуса 200, если создание будет успешным, или код 4xx/5xx, если он не удался. config.xml - это формат, используемый Jenkins для хранения проекта в файловой системе, поэтому вы можете увидеть их примеры в домашнем каталоге Jenkins или получить конфигурацию XML существующих заданий из /job/JOBNAME/config.xml.

Ответ 2

API требует, чтобы в post-данные был передан файл config.xml. Я предположил, что, подобно графическому интерфейсу, он будет создавать базовый, автоматически. Это не вариант

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

config.xml:

<?xml version='1.1' encoding='UTF-8'?>
<org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject plugin="[email protected]">
  <actions/>
  <description></description>
  <displayName>Test5</displayName>
  <properties>
    <org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig plugin="[email protected]">
      <dockerLabel></dockerLabel>
      <registry plugin="[email protected]"/>
    </org.jenkinsci.plugins.pipeline.modeldefinition.config.FolderConfig>
  </properties>
  <folderViews class="jenkins.branch.MultiBranchProjectViewHolder" plugin="[email protected]">
    <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
  </folderViews>
  <healthMetrics>
    <com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric plugin="[email protected]">
      <nonRecursive>false</nonRecursive>
    </com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric>
  </healthMetrics>
  <icon class="jenkins.branch.MetadataActionFolderIcon" plugin="[email protected]">
    <owner class="org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject" reference="../.."/>
  </icon>
  <orphanedItemStrategy class="com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy" plugin="[email protected]">
    <pruneDeadBranches>true</pruneDeadBranches>
    <daysToKeep>-1</daysToKeep>
    <numToKeep>-1</numToKeep>
  </orphanedItemStrategy>
  <triggers/>
  <disabled>false</disabled>
  <sources class="jenkins.branch.MultiBranchProject$BranchSourceList" plugin="[email protected]">
    <data>
      <jenkins.branch.BranchSource>
        <source class="org.jenkinsci.plugins.github_branch_source.GitHubSCMSource" plugin="[email protected]">
          <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>