4

私は、TeamCity で実行されているほとんどの Web ビルドおよびデプロイ構成を持っています。これは、基本的に MSBuild を使用して、サイトを Web サーバーに自動的にデプロイします。MSDeploy は、ターゲット サーバー上ですべてを既定で読み取り専用に設定します。AppPool ID が 1 つのフォルダーにのみ書き込みアクセスできるようにする必要があります。

ケビン・リーサムの記事を見つけて、そこに90%到達しました。Kevin は、次の行に沿って ProjectName.wpp.targets というファイルを作成することで、MSBuild Web Publish Pipeline にフックする方法を説明しています。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
     <!--Extends the AfterAddIisSettingAndFileContentsToSourceManifest action do also set ACLs -->

    <IncludeCustomACLs>TRUE</IncludeCustomACLs>

    <AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''">
      $(AfterAddIisSettingAndFileContentsToSourceManifest);
      SetCustomACLs;
    </AfterAddIisSettingAndFileContentsToSourceManifest>
  </PropertyGroup>
  <Target Name="SetCustomACLs" Condition="'$(IncludeCustomACLs)'=='TRUE'">
    <Message Text="Adding Custom ACls" />
    <ItemGroup>
      <!-- Ensure the AppPool identity has write access to the Files directory -->
      <MsDeploySourceManifest Include="setAcl" Condition="$(IncludeSetAclProviderOnDestination)">
        <Path>$(_MSDeployDirPath_FullPath)\files</Path>
        <setAclAccess>Read,Write,Modify</setAclAccess>
        <setAclResourceType>Directory</setAclResourceType>
        <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
      </MsDeploySourceManifest>
    </ItemGroup>
  </Target>
</Project>

これはほとんど機能しているので、私は夢中になっています。ACL はマニフェストに追加されますが、問題は、ターゲット サーバー上の IIS Web アプリに対する相対パスではなく、ビルドの場所に基づいて絶対パスを生成することです。生成されたマニフェストは次のようになります (問題のない人を保護するために一部の名前は変更されています)。

<?xml version="1.0" encoding="utf-8"?>
<sitemanifest>
  <IisApp path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" managedRuntimeVersion="v4.0" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclResourceType="Directory" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" />
  <setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files" setAclResourceType="Directory" setAclAccess="Read,Write,Modify" />
</sitemanifest>

これは実際には正しいように見えます。最後の行は wpp.targets ファイルからのカスタム ACL です。ただし、MSDeploy がこれをターゲット サーバーに送信すると、次のようになります。

2>Web 配置の開始 アプリケーション/パッケージを https://webhostingprovider.biz:8172/msdeploy.axd?site=IisWebAppName に発行します ...
2>サイトマニフェスト (sitemanifest) を追加します。
2>パス (IisWebAppName) の ACL を追加する
2>パス (IisWebAppName) の ACL を追加する
2>パスの ACL の追加 (C:\SolutionPath\IisWebAppname\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files)
2>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5): エラー ERROR_USER_NOT_AUTHORIZED_FOR_SETACL: Web 配置タスクが失敗しました。(Web 管理サービスを使用して接続しているときに、指定されたプロバイダー ("setAcl") で操作を完了できませんでした。これは、サーバー管理者がこの操作に対してユーザーを承認していない場合に発生する可能性があります。setAcl http://go.microsoft.com/ fwlink/?LinkId=178034

IisWebAppNameからの相対パス名ではなく、絶対パス名を使用して出力されるカスタム ACL パスに全体が当てはまります。理由がわかりません!!

助けてください :)

4

1 に答える 1

1

構文を使用して、別のパラメーターの値を取るProviderPathパラメーターを作成する必要があります。DefaultValue{param name}

すべてのアクションを実行する別の質問に含めたヘルパーを次に示します。

<ItemDefinitionGroup>
  <AdditionalAcls>
    <AclAccess>Write</AclAccess>
    <ResourceType>Directory</ResourceType>
  </AdditionalAcls>
</ItemDefinitionGroup>

<PropertyGroup>
  <AfterAddIisSettingAndFileContentsToSourceManifest>
    $(AfterAddIisSettingAndFileContentsToSourceManifest);
    AddAdditionalAclsToSourceManifest;
  </AfterAddIisSettingAndFileContentsToSourceManifest>
  <AfterAddIisAndContentDeclareParametersItems>
    $(AfterAddIisAndContentDeclareParametersItems);
    AddAdditionalAclsDeclareParameterItems
  </AfterAddIisAndContentDeclareParametersItems>
</PropertyGroup>

<Target Name="AddAdditionalAclsToSourceManifest">
  <ItemGroup Condition="'@(AdditionalAcls)' != ''">
    <MsDeploySourceManifest Include="setAcl">
      <Path>$(_MSDeployDirPath_FullPath)\%(AdditionalAcls.Identity)</Path>
      <setAclResourceType Condition="'%(AdditionalAcls.ResourceType)' != ''">%(AdditionalAcls.ResourceType)</setAclResourceType>
      <setAclAccess>%(AdditionalAcls.AclAccess)</setAclAccess>
      <AdditionalProviderSettings>setAclResourceType;setAclAccess</AdditionalProviderSettings>
    </MsDeploySourceManifest>
  </ItemGroup>
</Target>

<Target Name="AddAdditionalAclsDeclareParameterItems">
  <ItemGroup Condition="'@(AdditionalAcls)' != ''">
    <MsDeployDeclareParameters Include="Add %(AdditionalAcls.AclAccess) permission to %(AdditionalAcls.Identity) Folder">
      <Kind>ProviderPath</Kind>
      <Scope>setAcl</Scope>
      <Match>^$(_EscapeRegEx_MSDeployDirPath)\\@(AdditionalAcls)$</Match>
      <Description>Add %(AdditionalAcls.AclAccess) permission to %(AdditionalAcls.Identity) Folder</Description>
      <DefaultValue>{$(_MsDeployParameterNameForContentPath)}/@(AdditionalAcls)</DefaultValue>
      <DestinationContentPath>$(_DestinationContentPath)/@(AdditionalAcls)</DestinationContentPath>
      <Tags>Hidden</Tags>
      <ExcludeFromSetParameter>True</ExcludeFromSetParameter>
      <Priority>$(VsSetAclPriority)</Priority>
    </MsDeployDeclareParameters>
  </ItemGroup>
</Target>

次のように宣言して使用できます。

<ItemGroup>
    <AdditionalAcls Include="MyRelativeWritableDirectory" />
</ItemGroup>

このソリューションは現在、パスにバックスラッシュが必要ない場合 (つまり、ルート ディレクトリのみの場合) にのみ機能することに注意してください。サブディレクトリが必要な場合は、「SkipDeleteItems」(その回答の後半) に使用するトリックを盗んで、正規表現でエスケープされたパス メタデータを各項目に追加する必要があります。

于 2012-10-17T10:40:20.067 に答える