Approot и sitesroot в Azure - PullRequest
       21

Approot и sitesroot в Azure

3 голосов
/ 18 июня 2011

Моя веб-роль Azure должна иметь возможность удалять временные локальные файлы, хранящиеся в подпапке App_Data.Я хочу использовать ICACLS в задаче запуска с повышенными правами Azure, чтобы IIS мог сделать это следующим образом:

ICACLS App_Data / grant "IIS_IUSRS" :( OI) (CI) F

Однако мойзадача запуска выполняется в:

E: \ Approot \ bin

В то время как корневая папка, в которой веб-приложение фактически заканчивается и выполняется, выглядит так:

E: \ sitesroot \ 0

Я не хочу жестко задавать этот путь на случай, если Microsoft изменит его.Есть ли способ получить этот путь из задачи запуска или я могу положиться на это место назначения?

Чтобы проверить это в ASPX, я добавляю:

Label1.Text = "MapPath: " + Server.MapPath("~/");
Label2.Text = "RoleRoot: " + Environment.GetEnvironmentVariable("RoleRoot");

Когда я запускаю это наразвернутый экземпляр, я получаю:

MapPath: E: \ sitesroot \ 0 \ RoleRoot:

т.е. RoleRoot пуст.

Так как я могу получить результат Server.MapPath ( "~ /");в задаче запуска?

Ответы [ 4 ]

3 голосов
/ 03 июня 2013

Вместо использования icacls из командной строки используйте сценарий Powershell, поскольку Powershell позволяет перечислять веб-сайты в IIS и получать путь к физической папке.

К сожалению, вы не можете установить сценарий Powershell какзадача запуска.Поэтому вам нужно создать обычный файл CMD или BAT, а затем в этом файле попросить Powershell выполнить ваш сценарий.

Файл CMD:

PowerShell -ExecutionPolicy Unrestricted .\Setup.ps1 >> %TEMP%\Setup-DebugLog.txt 2>&1
exit /B 0

Первая строка выполняетСценарий Powershell и сохраняет весь вывод в файл Setup-DebugLog.txt.Вторая строка гарантирует, что файл CMD возвращает OK обратно в Windows Azure, поэтому Azure знает, что в сценарии запуска все прошло хорошо.

Вот сценарий Powershell, который я использую для установки разрешений для папок в App_Data.папка:

Import-Module WebAdministration
cd IIS:\Sites
$dir = Get-ChildItem
$timeout = 0
while ($dir -eq $NULL -and $timeout -lt 11)
{
    "IIS Site not ready. Waiting for 2 seconds..."
    [System.Threading.Thread]::Sleep(2000)
    $timeout++
    $dir = Get-ChildItem
}

if ($dir -eq $NULL)
{
    "IIS Site still not ready. Aborting."
}
else
{
    "IIS site ready."
    Set-Location $dir.physicalPath
    "Location is $($dir.physicalPath)"
    $acl = (Get-Item App_Data).GetAccessControl("Access")
    $rule = New-Object System.Security.AccessControl.FileSystemAccessRule("Network Service", "Modify, Write", "ContainerInherit, ObjectInherit", "None", "Allow")
    $acl.AddAccessRule($rule)
    Set-Acl App_Data $acl
    "Permission added."
}

Она начинается с импорта модуля WebAdministration, который позволяет Powershell взаимодействовать с IIS.Затем он пытается перечислить сайты.Но вот интересный вызов.Потому что задача запуска запускается до того, как ваш веб-сайт был развернут в IIS.Таким образом, вам нужно настроить запуск задачи как фоновую задачу, а затем подождать, пока сайт не будет развернут.Таким образом, код пытается перечислить веб-сайты, и если веб-сайт не найден, он ждет 2 секунды, а затем пытается снова.Он делает это в течение 20 секунд, а затем время ожидания.Если веб-сайт готов, то физический путь найден, и FileSystemAccessRule добавлен в ACL-список папки App_Data.Вы можете изменить разрешения, добавленные в соответствии с вашими потребностями.Обратите внимание, что в этом сценарии предполагается, что в IIS будет только 1 сайт.Если вы развернули более 1 веб-сайта, этот сценарий может не работать, и вам придется адаптировать код.

Для полноты, вот XML, который вы должны добавить к своему ServiceDefinition.csdef:

<Startup>
  <Task commandLine="Setup.cmd" executionContext="elevated" taskType="background" />
</Startup>

И Setup.cmd, и Setup.ps1 должны быть размещены в корне вашего веб-сайта.Если вы хотите, чтобы они были помещены в подпапку вашего веб-сайта, вы можете сделать это, но затем вам придется обновить атрибут commandLine в элементе Task на «Subfolder \ Setup.cmd», и вам потребуетсяЧтобы обновить путь к файлу Powershell в файле CMD:

PowerShell -ExecutionPolicy Unrestricted .\Subfolder\Setup.ps1 >> %TEMP%\Setup-DebugLog.txt 2>&1

Также обратите внимание, что существуют некоторые различия в вызове сценария Powershell между Powershell v1 и v2.Если я правильно помню, Windows 2008 в Windows Azure работает под управлением Powershell v1, а Windows 2008 R2 и новее - под управлением Powershell v2.Поэтому, если вы используете Windows 2008 в Azure, вам нужно изменить строку, которая вызывает скрипт Powershell, поскольку есть некоторая разница в настройке политики выполнения.

3 голосов
/ 22 февраля 2012

Почему бы не получить это относительно? Диск, на котором развернуты и sitesroot , и подход , похоже, переключается между E: \ и F: \, но я думаю, что сейчас безопаснее предположить, что они будут развернуты как одноуровневые. папки.

Вот наша задача запуска, которая копирует файлы из папок sitesroot:

xcopy "../../sitesroot/0/bin" "../../sitesroot/1/bin" /y /i /S
xcopy "../../sitesroot/0/bin" "../../sitesroot/2/bin" /y /i /S
xcopy "../../sitesroot/0/bin" "../../sitesroot/3/bin" /y /i /S
xcopy "../../sitesroot/0/bin" "../../sitesroot/4/bin" /y /i /S
xcopy "../../sitesroot/0/bin" "../../sitesroot/5/bin" /y /i /S
2 голосов
/ 18 июня 2011

Существует переменная окружения с именем% ROLEROOT%, которая определяет путь к вашему приложению.

string appRoot = Environment.GetEnvironmentVariable("RoleRoot");

appRoot = Path.Combine(appRoot + @"\", @"approot\");

Подробнее об этом здесь .

1 голос
/ 19 июня 2011

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

...