2012-10-16 3 views
4

J'ai une configuration de build-and-deployment Web fonctionnant principalement dans TeamCity, qui utilise MSBuild pour déployer automatiquement le site sur un serveur Web. MSDeploy définit tout sur Readonly sur le serveur cible par défaut, et j'ai besoin de l'identité AppPool pour avoir un accès en écriture à un seul dossier.Définition des listes de contrôle d'accès lors du déploiement Web via MSBuild

J'ai trouvé an article by Kevin leetham qui me procure 90% du chemin. Kevin décrit comment il est possible de connecter le Web MSBuild Publier Pipeline en créant un fichier appelé ProjectName.wpp.targets, le long de ces lignes:

<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> 

Ceci est si près de travail qu'il conduit me fou. L'ACL est ajouté au manifeste, mais le problème est qu'il génère un chemin absolu basé sur l'emplacement de construction, plutôt que d'être relatif à l'application Web IIS sur le serveur cible. le manifeste généré est comme ça (certains noms ont été changés pour protéger les innocents):

<?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> 

Cela semble en fait correcte, la dernière ligne est mon ACL personnalisée à partir Teh fichier wpp.targets. Toutefois, lorsque MSDeploy envoie au serveur cible, voici ce qui se passe:

2>Start Web Deploy Publish the Application/package to https://webhostingprovider.biz:8172/msdeploy.axd?site=IisWebAppName ... 
2>Adding sitemanifest (sitemanifest). 
2>Adding ACL's for path (IisWebAppName) 
2>Adding ACL's for path (IisWebAppName) 
2>Adding ACL's for path (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 ERROR_USER_NOT_AUTHORIZED_FOR_SETACL: Web deployment task failed. (Could not complete an operation with the specified provider ("setAcl") when connecting using the Web Management Service. This can occur if the server administrator has not authorized the user for this operation. setAcl http://go.microsoft.com/fwlink/?LinkId=178034

L'ensemble tombe sur mon chemin d'ACL personnalisé, qui vient à l'aide d'un nom de chemin absolu au lieu d'être par rapport à IisWebAppName. Je ne peux pas comprendre pourquoi !!

Aide s'il vous plaît :)

Répondre

1

Vous devez créer un paramètre ProviderPath avec un DefaultValue qui prend sa valeur d'un autre paramètre en utilisant la syntaxe {param name}.

est ici une aide, j'inclus sur another question qui exécute toutes les actions:

<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> 

Vous pouvez l'utiliser en déclarant:

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

S'il vous plaît noter que cette solution ne fonctionne actuellement si vous n'a pas besoin d'une barre oblique inverse dans le chemin (c'est-à-dire s'il s'agit d'un répertoire racine uniquement). Si vous avez besoin d'un sous-répertoire, vous devrez voler l'astuce que j'utilise pour "SkipDeleteItems" (plus loin dans cette réponse) pour ajouter des métadonnées de chemin d'échappement regex à chaque élément.

+0

Cela n'a pas fonctionné pour moi. J'ai la sortie suivante: 2> Démarrer Web Deploy Publier l'application/package sur https: // serveur: 8172/msdeploy.axd? Site = IisWebAppname ... 2> Ajout de sitemanifest (sitemanifest). 2> Ajout d'ACL pour le chemin (IisWebAppname) 2> Ajout d'ACL pour le chemin (IisWebAppname) 2> Ajout d'ACL pour chemin ({IIS Web Nom de l'application}/fichiers) [snip] 2> Échec de la publication à déployer. –

+0

Quelle est l'erreur réelle? Essayez d'activer 'UseMsDeployExe' dans votre pubxml pour voir ce qu'il envoie réellement à' msdeploy.exe' –

+0

l'erreur est que la chaîne littérale "{Nom de l'application Web IIS}/files" est utilisée comme chemin au lieu du nom de l'application web actuall . Le serveur tearget rejette ensuite la requête car son chemin est invalide. –

Questions connexes