Как сделать задачи запуска идемпотентными?
У меня есть несколько задач запуска в пакетных файлах. В частности, я называю ИРИ appcmd.exe
настроить IIS. Предполагается, что задачи запуска в Azure являются идемпотентными (т. Е. Могут запускаться повторно с одними и теми же результатами) в случае перезапуска роли по какой-либо причине. К сожалению, многие из моих команд конфигурации IIS потерпят неудачу во второй раз, например, потому что они удаляют узел конфигурации в первый раз, который затем не присутствует при последующих запусках.
У меня вопрос, как мне сделать эти задачи запуска идемпотентными? Есть ли способ заставить appcmd.exe не выбрасывать ошибки? Есть ли способ заставить оболочку отлавливать ошибки? Есть ли способ заставить платформу Azure игнорировать ошибки?
Вот пример моих задач запуска. Это все содержится в командном файле, configiis.cmd
,
@REM Enable IIS compression for application/json MIME type
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json',enabled='True']" /commit:apphost
%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/json; charset=utf-8',enabled='True']" /commit:apphost
@REM Set IIS to automatically start AppPools
%windir%\system32\inetsrv\appcmd.exe set config -section:applicationPools -applicationPoolDefaults.startMode:AlwaysRunning /commit:apphost
@REM Set IIS to not shut down idle AppPools
%windir%\system32\inetsrv\appcmd set config -section:applicationPools -applicationPoolDefaults.processModel.idleTimeout:00:00:00 /commit:apphost
@REM But don't automatically start the AppPools that we don't use, and do shut them down when idle
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='Classic .NET AppPool'].startMode:OnDemand" "/[name='Classic .NET AppPool'].autoStart:False" "/[name='Classic .NET AppPool'].processModel.idleTimeout:00:01:00" /commit:apphost
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='ASP.NET v4.0'].startMode:OnDemand" "/[name='ASP.NET v4.0'].autoStart:False" "/[name='ASP.NET v4.0'].processModel.idleTimeout:00:01:00" /commit:apphost
%windir%\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/applicationPools "/[name='ASP.NET v4.0 Classic'].startMode:OnDemand" "/[name='ASP.NET v4.0 Classic'].autoStart:False" "/[name='ASP.NET v4.0 Classic'].processModel.idleTimeout:00:01:00" /commit:apphost
@REM remove IIS response headers
%windir%\system32\inetsrv\appcmd.exe set config /section:httpProtocol /-customHeaders.[name='X-Powered-By']
5 ответов
Помимо ответа @Syntaxc4: рассмотрите возможность использования крошки (файла) локально. В вашем скрипте проверьте наличие известного файла (который вы создаете). Если он не существует, просмотрите сценарий запуска, а также создайте файл с хлебными крошками. В следующий раз, когда vm запустится, он снова проверит наличие файла breadcrumb и, если он существует, выйдет из файла cmd. Если файл breadcrumb исчезает, это обычно означает, что ваш виртуальный компьютер был восстановлен где-то еще (либо новый экземпляр, либо повторно созданный экземпляр, возможно, на другом оборудовании), и потребуется настройка IIS.
MSDN теперь содержит отличное руководство для этого, обрабатывая коды ошибок из APPCMD.
http://msdn.microsoft.com/en-us/library/windowsazure/hh974418.aspx
После любой операции appcmd вы можете сделать следующее:
IF %ERRORLEVEL% EQU 183 DO VERIFY > NUL
и игнорировать любой допустимый код ошибки.
Вам нужно проверить, присутствует ли параметр конфигурации, прежде чем пытаться его удалить (добавить условную логику). Это может быть достигнуто путем:
'appcmd.exe list config -details'
Получение возвращаемого значения даст вам что-то для сравнения, будь то длина вывода или фактическое значение.
Основываясь на предложении Дэвида Макогона, я добавил следующее в начало каждого из моих файлов.cmd. Это, кажется, делает трюк. Он создаст файл флага (который Дэвид назвал файлом крошки) в том же каталоге, что и исполняемый скрипт, а затем проверит его при последующих запусках.
@REM A file to flag that this script has already run
@REM because if we run it twice, it errors out and prevents the Azure role from starting properly
@REM %~n0 expands to the name of the currently executing file, without the extension
SET FLAGFILE=c:\%~n0-flag.txt
IF EXIST "%FLAGFILE%" (
ECHO %FLAGFILE% exists, exiting startup script
exit /B
) ELSE (
date /t > %FLAGFILE%
)
Я настоятельно рекомендую использовать /config:* /xml
на конце вашего list
команда. Для получения дополнительной информации о том, как я сделал iis idempotent, пожалуйста, посмотрите на: https://github.com/opscode-cookbooks/iis
Chef - это одна из нескольких платформ управления конфигурацией, и я только предлагаю посмотреть на нее код (в рубине), который делает идемпотентным, перечисляя текущие настройки и сравнивая их с настройками, которые запрашиваются для изменения.