Мы запускаем приложение Golang, которое внутренне запускает модуль автообновления для получения обновлений по беспроводной сети.Во время нового обновления модуль автообновления загружает новую версию с s3 и вызывает скрипт bash автообновления, присутствующий в том же рабочем каталоге, что и исполняемый файл.Шаги, выполняемые сценарием автоматического обновления bash, поясняются в терминах управления процессами, которые обрабатываются с помощью systemd и без него.
Выполнение без Systemd
- Убивает работающий в данный момент golangприложение через PID
- Запускает только что загруженный двоичный файл golang.
- В новой версии представлен API проверки работоспособности, который вызывается скриптом для проверки работоспособности этой версии.
- Если нетздоров, откат выполнен.Новая версия останавливается, и запускается более старая версия.
В golang код выполнения сценария написан так, что при запуске сценария автообновления он отключается от жизненного цикла приложения golang.т.е. скрипт bash (дочерний процесс) продолжает выполнение даже после того, как родитель (приложение golang) был убит.Он отлично работает при запуске из IDE GoLand.
Проблема: выполнение через Systemd
Нам требовалась более чистая система для обработки функций запуска, остановки, перезапуска при сбое.,Поэтому мы решили запустить приложение как службу systemd. Шаги те же, что и выше, но выполняются с использованием systemctl
- Убивает текущее приложение golang: "systemctl stop goapp.service"
- Обновляет службу systemd с помощью нового пути к исполняемому файлу: "systemctl daemon-reload"
- Перезапускает службу systemd: "systemctl restart goapp.service"
- Если состояние не исправно, выполняется откат.Новая версия остановлена, файл службы systemd обновлен более старой версией и запущена более старая версия.
При запуске приложения через systemd, сценарий завершается, как только останавливается служба systemctl.с помощью команды "sudo systemctl stop goapp.service" во время шага 1, указанного выше .Это означает, что жизненный цикл скрипта, выполняемого приложением golang, явно связан с жизненным циклом службы systemd.Как я могу отсоединить его от области действия службы systemd?
Файл службы Systemd
[Unit]
Description=Goapp
After=docker.service
Requires=docker.service
Requires=docker-mysql.service
Requires=docker-redis.service
StartLimitInterval=200
StartLimitBurst=5
[Service]
User=root
Environment=AWS_SHARED_CREDENTIALS_FILE=/home/username/.aws/credentials
Restart=on-failure
RestartSec=30
WorkingDirectory=/home/username/go/src/goapp-v2.0.0
ExecStart=/home/username/go/src/goapp-v2.0.0/goexecutable --autoupdate=true
[Install]
WantedBy=multi-user.target
Раздел кода Golang, который вызывает bashscript для автообновления
func scriptExecutor(argsliceString []string, remoteVersion *semver.Version, localVersion *semver.Version) {
newVersion := fmt.Sprint(remoteVersion)
previousVersion := fmt.Sprint(localVersion)
argslice := append(argsliceString, newVersion, previousVersion)
scriptParams := append([]string{"./autoupdate-script.sh"}, argslice...)
Info("Autoupdater - New version ", newVersion)
Info("Autoupdater - Existing Version ", previousVersion)
Info("Autoupdater - Executing shell script to upgrade go app.Passing parameters ", scriptParams) // ./autoupdate-script.sh goexecutable 7.1.0 7.0.0
cmd := exec.Command("sudo", scriptParams...)
err := cmd.Start()
if err!=nil{
Info(err)
}
cmd.Process.Release()
}
Сообщения о том, «как запустить скрипт в Golang и отсоединить / отсоединить его», были опубликованы, но не удалось найти ни одного сообщения по этому типу проблемы.Пожалуйста, помогите мне решить проблему или исправьте меня, если в моем понимании есть ошибки.