2016-08-16 8 views
2

ПОМОЩЬ!Жесткая загрузка исполняемого jar с init.d запускается как root вместо пользователя

Я использую встроенный сценарий запуска с SpringBoot 1.3.6 и Gradle. О, и задача distZip, чтобы застегнуть вещи.

В какой-то момент это все работало неплохо ... тогда я это сделал - я не знаю, что - ввергнуть его.

Я установил пакет (распаковал Zip, в основном) на мой малиновый Pi, и проверил право собственности и разрешения. Все принадлежит пользователю, которому я хочу запустить приложение, как (пользовательская группа «appservice» «pi») и подтвердил, что разрешения для файлов - если что-то, слишком разрешительное (755 для сценария myapp/bin/myapp и почти все остальное).

Я установил символическую ссылку в /etc/init.d, указав на ~ appservice/myapp/bin/myapp, и я запустил update-rc.d myapp по умолчанию, чтобы получить его в системе. Обратите внимание, что сама символическая ссылка принадлежит root/root, но я считаю, что она должна быть, не так ли?

Я вижу две проблемы, которые, я думаю, взаимосвязаны.

Во-первых, независимо от того, как я запускаю сценарий (при загрузке с init.d или вручную с помощью «sudo service myapp start»), он запускается с правами root (в частности, пути, которые приложение пытается использовать для доступа файлы выходят как/root/myapp/files вместо/home/appservice/myapp/files).

Во-вторых, приложение выйдет из строя ... в частности, я получаю сообщение syslog «Время запуска операции myapp.service завершено». за которым следует упорядоченное закрытие приложения. О, и связанный ... если я запускаю с «sudo service myapp start», команда никогда не возвращается. Что является новым ...

В-третьих, выход журнала приложения будет в/var/log/syslog вместо /var/log/myapp.log, который, похоже, соответствует тому, что говорит документация Spring Boot.

Я нахожусь в окончательном регрессионном тестировании развертывания для этого и (знаменитые последние слова). Я недавно ничего не изменил ... :) Нет, действительно, самое последнее изменение, имеющее отношение к распространению, заключалось в добавлении src/main/dist, и он работал после этого (запуск при загрузке как правильный пользователь).

Я бы опубликовал сценарий запуска, но AFAIK это скрипт по умолчанию, предоставленный Spring Boot, когда вы используете задачу springBoot {executable = true}.

Вот мой полный файл build.gradle ... Я ничего не вижу, но, возможно, вы это сделаете.

buildscript { 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.6.RELEASE") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'idea' 
apply plugin: 'spring-boot' 
apply plugin: 'application' 

apply from: 'gradle/gradle/helpers.gradle' 

mainClassName = 'app.Application' 

if (!hasProperty('mainClass')) { 
    ext.mainClass = 'app.Application' 
} 

springBoot { 
    executable = true 
} 

repositories { 
    mavenCentral() 
} 

sourceSets { 
    main { 
    java  { srcDir 'src/main/java' } 
    resources { srcDir '/src/main/resources' } 
    } 
    test { 
    java  { srcDir 'src/test/java' } 
    resources { srcDir 'src/test/resources' } 
    } 
} 

project.ext { 
    applicationVersion = "0.1.5-alpha" 

    applicationRelease = isApplicationRelease() 
    applicationDate = new Date() 
    applicationRevision = getRevision() 

    applicationVersionSnapshot = (!applicationRelease) ? "+SNAPSHOT.${asUTC(applicationDate, 'yyMMddHHmm')}.git${applicationRevision}" : "" 
    applicationVersionFull = "${applicationVersion}${applicationVersionSnapshot}" 
} 

jar { 
    baseName = 'myapp' 
    version = '0.9.0' 
} 

sourceCompatibility = 1.8 
targetCompatibility = 1.8 

dependencies { 

    compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.2' 
    compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3.6' 
    compile group: 'commons-cli', name:'commons-cli', version: '1.3.1' 
    compile group: 'org.json', name:'json', version: '20140107' 

    compile "commons-codec:commons-codec:1.10" 

    compile("org.springframework.boot:spring-boot-starter-hateoas") 
    compile("org.springframework.boot:spring-boot-starter-web") 
    compile("org.springframework.boot:spring-boot-starter-thymeleaf") 
    compile("org.springframework.boot:spring-boot-starter-mail") 
    compile("org.springframework.boot:spring-boot-starter-security") 
    compile("org.springframework:spring-web") 
    compile("org.springframework:spring-messaging") 
    compile("joda-time:joda-time:2.2") 
    compile("com.fasterxml.jackson.core:jackson-databind") 
    compile("com.googlecode.json-simple:json-simple") 
    compile("org.jdom:jdom:2.0.0") 
    compile("org.hibernate:hibernate-validator") 
    compile("org.apache.tomcat.embed:tomcat-embed-el") 
    compile("org.apache.commons:commons-io:1.3.2") 
    compile("org.kamranzafar:jtar:2.3") 
    compile("org.thymeleaf.extras:thymeleaf-extras-springsecurity4") 
    compile("com.jcraft:jsch:0.1.53") 
    compile("javax.jmdns:jmdns:3.4.1") 
    testCompile("org.springframework.boot:spring-boot-starter-test") 


} 

task wrapper(type: Wrapper) { 
    gradleVersion = '2.14' 
} 
+0

Другой немного странности, которые могут быть связаны и которые, похоже, указывает на какой-то пользователь/группа/разрешений screwup ... когда я просматриваю zip-файл, он заканчивается тем, что находится в user/group appservice/appservice. когда я пытаюсь chgrp файлы для группировки ip, я получаю «операцию не разрешенной», даже если пользовательские приложения обслуживают как группу pi, так и группу appservice ... как подтверждено «info appservice» –

+0

Если вы готовы и можете чтобы переключиться на systemd для управления вашим приложением, взгляните на этот ответ: http://stackoverflow.com/a/22121547/272180 – yglodt

+0

ДА! Кажется, что он работал отлично, yglodt. Спасибо. –

ответ

1

Я бы рекомендовал запустить и управлять своим приложением с помощью systemd.

Это позволяет легко запускать приложение под конкретным пользователем.

Для этого перейдите по следующим образом:

Во-первых, создать файл описания службы /etc/systemd/system/myapp.service с этим содержанием:

[Unit] 
Description=My App 

[Service] 
User=nobody 
# The configuration file application.properties should be here: 
WorkingDirectory=/home/appservice/myapp/files 
ExecStart=/usr/bin/java -Xmx256m -jar myapp.jar 
SuccessExitStatus=143 

[Install] 
WantedBy=multi-user.target 

Затем уведомить systemd нового служебного файла:

systemctl daemon-reload 

и включите его, поэтому он работает на ботинках:

systemctl enable myapp.service 

В конце концов, вы можете использовать следующие команды для запуска/остановки свой новый сервис:

systemctl start myapp 
systemctl stop myapp