Проблема с подчиненным Jenkins - неверный заголовок потока: 099EACED - PullRequest
0 голосов
/ 29 июня 2018

Jenkins 2.7.4 был установлен на сервере RedHat, а подчиненные Linux настроены с помощью опции «Запустить агент через выполнение команды на мастере». Мы создали скрипт Shell, и он отлично работает в версии Jenkins 2.7.4.

Теперь мы обновили Jenkins до 2.121.1. Теперь тот же скрипт выдает ошибку

<=== [JENKINS REMOTING CAPACITY] ===> Исключение в теме "main" java.io.StreamCorruptedException: неверный заголовок потока: 099EACED в java.io.ObjectInputStream.readStreamHeader (ObjectInputStream.java:808) в java.io.ObjectInputStream. (ObjectInputStream.java:301) в hudson.remoting.ObjectInputStreamEx. (ObjectInputStreamEx.java:48) в hudson.remoting.ChannelBuilder.makeTransport (ChannelBuilder.java:478) на hudson.remoting.ChannelBuilder.negotiate (ChannelBuilder.java:433) в hudson.remoting.ChannelBuilder.build (ChannelBuilder.java:354) в hudson.remoting.Launcher.main (Launcher.java:743) в hudson.remoting.Launcher.runWithStdinStdout (Launcher.java:691) в hudson.remoting.Launcher.run (Launcher.java:373) в hudson.remoting.Launcher.main (Launcher.java:283) ОШИБКА: соединение прекращено ОШИБКА: непредвиденная ошибка при запуске агента. Это возможно ошибка в Jenkins java.io.IOException: неожиданный EOF в hudson.remoting.ChunkedInputStream.readUntilBreak (ChunkedInputStream.java:99) в hudson.remoting.ChunkedCommandTransport.readBlock (ChunkedCommandTransport.java:39) в hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read (AbstractSynchronousByteArrayCommandTransport.java:35) в hudson.remoting.SynchronousCommandTransport $ ReaderThread.run (SynchronousCommandTransport.java:63) ОШИБКА: процесс завершен с кодом выхода 1 java.io.IOException: Неожиданный EOF в hudson.remoting.ChunkedInputStream.readUntilBreak (ChunkedInputStream.java:99) в hudson.remoting.ChunkedCommandTransport.readBlock (ChunkedCommandTransport.java:39) в hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read (AbstractSynchronousByteArrayCommandTransport.java:35) в hudson.remoting.SynchronousCommandTransport $ ReaderThread.run (SynchronousCommandTransport.java:63) Также: hudson.remoting.Channel $ CallSiteStackTrace: удаленный вызов rtt-ci-euhrhd0036vdeas at hudson.remoting.Channel.attachCallSiteStackTrace (Channel.java:1741) в hudson.remoting.Request.call (Request.java:202) в hudson.remoting.Channel.call (Channel.java:954) в hudson.slaves.SlaveComputer.setChannel (SlaveComputer.java:549) в hudson.slaves.SlaveComputer.setChannel (SlaveComputer.java:416) в hudson.slaves.CommandLauncher.launch (CommandLauncher.java:153) в hudson.slaves.SlaveComputer $ 1.call (SlaveComputer.java:288) в jenkins.util.ContextResettingExecutorService $ 2.call (ContextResettingExecutorService.java:46) в jenkins.security.ImpersonatingExecutorService $ 2.call (ImpersonatingExecutorService.java:71) на java.util.concurrent.FutureTask.run (неизвестный источник) на java.util.concurrent.ThreadPoolExecutor.runWorker (неизвестный источник) в java.util.concurrent.ThreadPoolExecutor $ Worker.run (неизвестный источник) at java.lang.Thread.run (неизвестный источник) hudson.remoting.RequestAbortedException в hudson.remoting.Request.abort (Request.java:340) в hudson.remoting.Channel.terminate (Channel.java:1038) в hudson.remoting.SynchronousCommandTransport $ ReaderThread.run (SynchronousCommandTransport.java:96)

Если я отключу порт SSHD в Manage Jenkins -> Configure Security, тогда я смогу запустить подчиненное устройство. Но в моем сценарии я вызову одно задание, используя Jenkins-cli.jar, чтобы скопировать двоичные файлы с главного на подчиненные. java -jar jenkins-cli.jar -s http://localhost:8080 --ssh -user username -i ~/.ssh/id_rsa build RTT/RTT-CI-Tools/RTT-CI-Tools-Distribute -s -p SLAVE_REGEX=slave name Я получаю сообщение как

"WARNING: No header 'X-SSH-Endpoint' returned by Jenkins" 

и сборка не запускается. Я также попытался заменить -ssh на -http в команде jenkins-cli.jar,

java -jar jenkins-cli.jar -s http://localhost:8080 -http -auth username:60b3450a883a2519592af84cdcd0d224 build $CI_JOB -s -p SLAVE_REGEX=$SLAVEHOST

Это запускает работу. Снова невозможно запустить подчиненную машину,

<=== [JENKINS REMOTING CAPACITY] ===> Исключение в потоке "main" java.io.StreamCorruptedException: неверный заголовок потока: 099FACED в java.io.ObjectInputStream.readStreamHeader (ObjectInputStream.java:808) в java.io.ObjectInputStream. (ObjectInputStream.java:301) в hudson.remoting.ObjectInputStreamEx. (ObjectInputStreamEx.java:48) в hudson.remoting.ChannelBuilder.makeTransport (ChannelBuilder.java:478) на hudson.remoting.ChannelBuilder.negotiate (ChannelBuilder.java:433) в hudson.remoting.ChannelBuilder.build (ChannelBuilder.java:354) в hudson.remoting.Launcher.main (Launcher.java:743) в hudson.remoting.Launcher.runWithStdinStdout (Launcher.java:691) в hudson.remoting.Launcher.run (Launcher.java:373) в hudson.remoting.Launcher.main (Launcher.java:283) использование: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:] порт] [-e escape_char] [-F configfile] [-i индивидуальный_файл] [-L [bind_address:] порт: хост: хост-порт] [-l логин_имя] [-m mac_spec] [-O ctl_cmd] [-o опция] [-p порт] [-R [bind_address:] порт: хост: хост-порт] [-S ctl_path] [-W хост: порт] [-w local_tun [: remote_tun]] [пользователь @] имя хоста [команда] ОШИБКА: непредвиденная ошибка при запуске агента. Вероятно, это ошибка в Jenkins ERROR: Соединение прервано java.io.IOException: Неожиданный EOF

Как решить эту проблему

1 Ответ

0 голосов
/ 12 августа 2018

неизмененный стандартный, неизмененный стандартный

Я полагаю, что что-то в вашем сценарии вмешивается в стандартный ввод.

Ваш сценарий должен передать весь поток stdin без изменений процессу агента Jenkins.

Универсальное решение

Команда OP для установки сеанса Jenkins отличается от моей, но, тем не менее, вы должны разбить свой сценарий запуска на 3 основные части:

Настройка: В этой части нет вмешательства в стандартный ввод или стандартный вывод.

Установить сеанс Jenkins: java -jar jenkins-cli.jar ...

Снесите: В этой части нет вмешательства в стандартный ввод или вывод.

#!/bin/bash

function set_up {
    # your set-up code here
}

function tear_down {
    # your tear-down code here
}

function main {
    # set-up (no stdin, no stdout)
    set_up "$@" < /dev/null > /dev/null || exit $?
    # establish Jenkins session
    java -jar jenkins-cli.jar -blah -blah -blah
    # tear-down (no stdin, no stdout)
    tear_down "$@" < /dev/null > /dev/null || exit $?
}
main "$@"

Но ... почему?

Задача вашего сценария запуска - установить нетронутый канал связи (через stdin и stdout) между мастером и агентом сборки.

              +------------+
"Hello Agent" |            |
   _ _    ----+            +----
    v               Hello Agent  ->
          ----+            +----
              |            |
              |            |  "Hello Master"
          ----+            +----   _ _
       <-  Hello Master             v
          ----+            +----
              |            |
              +------------+
                  launch
                  script

Если этот канал связи подделан, Дженкинс не будет работать.

              +------------+
"Hello Agent" |            |
   _ _    ----+            +-----------
    v            Hel PLZ SEND HELP!! t  ->
          ----+            +-----------
              |            |
              |            |  
          ----+            +----   | |
                                    ^
          ----+            +----
              |            |
              +------------+
                  launch
                  script

Некоторые команды Unix могут «проглотить» стандартный код вашего сценария запуска, если вы ничего не передаете в эту команду, и, следовательно, «повредить» канал связи. Рассмотрим следующий сценарий.

#!/bin/bash

function keep_stdin_intact {
    printf 'I do not consume any stdin, ' >&2
    echo 'and I do not alter the original stdout.' >&2
}

function swallow_stdin {
    echo 'I swallow stdin. Did you see any hexdump below?' >&2
    read yn  # read consumed some stdin
}

echo 'yes' | { keep_stdin_intact; cat -; } | xxd
echo 'yes' | { swallow_stdin; cat -; } | xxd

echo "no you can't now :P" | { swallow_stdin < /dev/null; cat -; } | xxd
  • Первый yes был передан по каналу и выгружен в шестнадцатеричном формате, потому что keep_stdin_intact не вмешивался в stdin, в данном случае это поток "yes".

  • Второй yes пропал, потому что swallow_stdin потреблял его, поэтому cat не имеет ничего для кошки, а xdd нечего читать.

  • Отправив /dev/null команде на проглатывание стандартного ввода, мы защитили наш собственный стандартный вывод.

Что случилось с ssh?

ssh - одна из злых команд, которые поглощают ваш стандартный ввод.

Допустим, вы хотите удалить некоторые файлы в агенте сборки до запуска agent.jar. Без образца вы можете написать:

ssh $OPTIONS "$remote" 'sudo rm -rf /var/log/nginx/*'
ssh $OPTIONS "$remote" 'cd $HOME && java -jar agent.jar'

^ Но это неправильно! Первая команда ssh поглотит ваш стандартный ввод, и сеансу Дженкинса нечего будет читать.

Первый ssh должен быть "замолчать". Передайте /dev/null как его стандартный номер.

ssh $OPTIONS "$remote" 'sudo rm -rf /var/log/nginx/*' < /dev/null
ssh $OPTIONS "$remote" 'cd $HOME && java -jar agent.jar'
...