Проблема с подчиненным Jenkins - неверный заголовок потока: 099EACED

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

Теперь мы обновили 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.ChannelBilder (javaBilder):433) в hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:354) в hudson.remoting.Launcher.main(Launcher.java:743) в hudson.remoting.Launcher.runWithStdinStdout(Launcher.java:691) в h.remoting.Launcher.run(Launcher.java:373) at hudson.remoting.Launcher.main(Launcher.java:283) ОШИБКА: соединение прервано ОШИБКА: непредвиденная ошибка при запуске агента. Вероятно, это ошибка в Jenkins java.io.IOException: неожиданное EOF в hudson.remoting.ChunkedInputStream.readUntilBreak(ChunkedInputStream.java:99) в hudson.remoting.ChunkedCommandTransport.readBlock(ChunkedCommandTransport.java39): AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousByteArrayCommandTransport.java:35) в hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:63) ОШИБКА. Процесс завершен с ошибочным выходом. readUntilBreak (ChunkedInputStream.java:99) по адресу hudson.remoting.ChunkedCommandTransport.readBlock(ChunkedCommandTransport.java:39) по адресу hudson.remoting.AbstractSynchronousByteArrayCommandTransport.read(AbstractSynchronousThromTransportHransTromTransport).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:15.slaves $1SudSudSududSudud.SlaudS $udsSlaSudSudSududSududSududSududSaudSlaSudSudSudSudSud = 1 $ -) в h.call(SlaveComputer.java:288) по адресу jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46) по адресу jenkins.security.ImpersonatingExecutorService$2.call(ImpersonatingExecutorService.javaurtil.Future. at ю).71 выполнить (неизвестный источник) в java.util.concurrent.ThreadPoolExecutor.runWorker(неизвестный источник) в java.util.concurrent.ThreadPoolExecutor$Worker.run(неизвестный источник) в java.lang.Thread.run(неизвестный источник) Причина: hudson.remoting.RequestAbortedException в hudson.remoting.Request.abort(Request.java:340) в hudson.remoting.Channel. прекратить (Channel.java:1038) в hudson.remoting.SynchronousCommandTransport$ReaderThread.run(SynchronousCommandTransport.java:96)

Если я отключу SSHD-порт в "Управление Jenkins -> Настройка безопасности", тогда я смогу запустить свое ведомое устройство. Но в моем сценарии я вызову одно задание, используя 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.ChannelBilder (javaBilder):433) в hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:354) в hudson.remoting.Launcher.main(Launcher.java:743) в hudson.remoting.Launcher.runWithStdinStdout(Launcher.java:691) в h.remoting.Launcher.run(Launcher.java:373) at hudson.remoting.Launcher.main(Launcher.java:283) usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-e escape_char] [-F configfile] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-R [bind_address:]port:host:hostport] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command] ERROR: Unexpected error in launching an agent. This is probably a bug in Jenkins ERROR: Connection terminated java.io.IOException: Unexpected EOF

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

1 ответ

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

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

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

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

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

Настройка: не вмешиваться в stdin или stdout в этой части.

Установить сессию Дженкинса: java -jar jenkins-cli.jar ...

Снесите: не вмешивайтесь в stdin или stdout в этой части.

#!/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 могут "проглотить" stdin вашего сценария запуска, если вы ничего не передаете в эту команду, и, следовательно, "повредить" канал связи. Рассмотрим следующий скрипт.

#!/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 ушел, потому что 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'
Другие вопросы по тегам