Назад | Перейти на главную страницу

Сценарий Upstart и командная строка: почему такая разница в поведении?

Я пытаюсь настроить Tomcat для запуска с выскочкой. Нахожу следующие работы:

  description "Tomcat Server"

  start on runlevel [2345]
  stop on runlevel [!2345]
  respawn
  respawn limit 10 5

  setuid tomcat

  env JAVA_HOME=/usr/lib/jvm/default-java
  env CATALINA_HOME=/opt/apache-tomcat-7.0.34

  script
    chdir $CATALINA_HOME
    exec $CATALINA_HOME/bin/catalina.sh run
  end script

Но если я удалю chdir, кот запускается, но с большим количеством FileNotFound исключения, когда мой .wars нагрузка. (Это .wars сами загружаются, но выдают исключения при загрузке.)

Обратите внимание, что это поведение разные из того, что я вижу, когда вызываю catalina.sh из командной строки. Вызов из командной строки, я могу запустить /opt/apache-tomcat-7.0.34/bin/catalina.sh run из любого каталога (без чдиринга) и все нормально.

Так почему chdir необходимо в моем сценарии выскочки? (Чем среда выскочки отличается от моей среды командной строки?)


Пример ошибок, которые я вижу с выскочкой, когда я не chdir:

Feb 22, 2013 3:00:11 AM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deploying web application archive my-war.war
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: my-war.log (Permission denied)
    at java.io.FileOutputStream.open(Native Method)

Это проблема с разрешением на запись. Пользователь tomcat не может создавать файл журнала в том месте, где он пытается их создать. Местоположение, в котором он пытается создать файлы журнала, зависит от того, как вы запускаете tomcat.

Мое внимание привлек этот фрагмент из вашего журнала:

java.io.FileNotFoundException: my-war.log (в разрешении отказано) в java.io.FileOutputStream.open (собственный метод)

В нем говорится, что пользователю (tomcat) не разрешено создавать файл my-war.log. Вот разные сценарии:

Выскочка с chdir

Запустите первые chdirs в $ CATALINA_HOME. Пользователь tomcat может создавать там файлы. Так что все работает.

Выскочка без chdir

Upstart запускается от имени пользователя root, поэтому каталог по умолчанию - /. Пользователь tomcat не может создавать там файлы. Таким образом, вы получаете ошибки отказа в разрешении.

Запуск кота из домашнего каталога

Теперь вы запускаете кота от имени себя из домашнего каталога. У вас есть разрешение на запись в собственный каталог. Так что все снова работает.

У меня нет доступа к новой версии с setuid поддержку, но я бы так поступил в вашем случае.

Похоже, проблема несоответствия среды. Скорее всего, это переменная среды, которая не устанавливается при запуске из выскочки. Может быть так setuid не устанавливает $USER или $HOME?

Поэтому я бы порекомендовал вам сравнить среды. Легким и простым способом было бы изменить ваш сценарий инициализации таким образом и перезапустить задание.

  script
    env > /tmp/env-upstart.log
    chdir $CATALINA_HOME
    exec $CATALINA_HOME/bin/catalina.sh run
  end script

Тогда также запустите env > /tmp/env-console.log когда вы обычно запускаете его с консоли (если вы используете sudo, затем сделайте это с помощью sudo env).

Затем сравните два /tmp/env-upstart.log и /tmp/env-console.log файлы (отсортируйте их и откройте с помощью vimdiff), и должно быть легко найти, какая переменная в env-upstart отсутствует в другом файле (или установлено значение, которое вы не ожидали).

Обновление 1

И если вы все еще получаете ошибки, я бы проверил следующее:

  • Разрешения пользователя: эффективные / реальные идентификаторы пользователей могут отличаться. Сравните вывод id, id -r -u, id -r -g, id -r -G, id -u, id -g, и id -G в обоих случаях.
  • Пределы процесса: Возможно, ваши сценарии-выскочки имеют более строгие ограничения. Попробуйте поставить ulimit -a сравнивать.
  • Странность оболочки: Маловероятно, но выскочка использует sh в то время как оболочка вашего пользователя, скорее всего, bash или zsh. Попробуйте запустить успешную команду из sh.
  • Отладить сценарий: Если вы все еще действительно застряли, бегите catalina.sh в режиме отладки. Это так же просто, как запустить его из выскочки следующим образом:

    exec /bin/sh -x $CATALINA_HOME/bin/catalina.sh run 2>/tmp/catalina-upstart.log
    

    Затем вы можете сравнить два журнала отладки и, возможно, определить, где два сценария сделали что-то другое.

Да, дело в разрешении. Но не имеет отношения к Upstart. Это потому, что в 'catalina.sh start', то есть в части 'start', настоящая команда:

  ...
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 "&"

Здесь выходной журнал полностью назначен. Пока в части RUN нет "$ CATALINA_OUT". Это приведет к упомянутой выше проблеме с разрешением на запись. А именно, если не назначен конкретный путь к выходному файлу, выходные данные пойдут либо в файл журнала, либо в соответствии с кодом your.war. Подобные нечеткие назначения журналов приводят к неопределенным проблемам с разрешениями.

Чтобы получить полный дамп всех элементов среды между запуском вашего сервера в командной строке по сравнению с запуском его в Upstart, попробуйте установить мой инструмент procnv, запустить его в обеих средах и сравнить выходные файлы:

Это доступно в архивах ubuntu raring и debian sid (и FreeBSD).