Setting ACLs During Web Deployment Through MSBuild

I mainly have a web assembly and deployment assembly working in TeamCity, which mainly uses MSBuild to automatically deploy a site to a web server. MSDeploy by default installs everything on Readonly on the target server, and I need the AppPool ID to have write access to only one folder.

I found an article by Kevin leetham that gives me 90% of the way. Kevin describes how to connect to MSBuild Web Publish Pipeline by creating a file called ProjectName.wpp.targets in the following lines:

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

It almost works so much that it drives me crazy. The ACL is added to the manifest, but the problem is that it generates an absolute path based on the assembly location, and not relative to the IIS web application on the target server. the generated manifest goes like this (some names have been changed to protect the innocent):

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

It really looks right, the last line is my custom ACL from the wpp.targets file. However, when MSDeploy sends this to the target server, this is what happens:

  2> Start Web Deploy Publish the Application / package to https://webhostingprovider.biz:8172/msdeploy.axd?site=IisWebAppName ...
 2> Adding sitemanifest (sitemanifest).
 2> Adding ACL for path (IisWebAppName)
 2> Adding ACL for path (IisWebAppName)
 2> Adding ACL 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 

It all depends on my custom ACL path, which is displayed using an absolute path name instead of referring to IisWebAppName. I can’t understand why!

Help me please:)

+4
source share
1 answer

You need to create the ProviderPath parameter using DefaultValue , which will take the value of another parameter using the {param name} syntax.

Here's a helper included in another question that performs all the 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> 

You can use it by declaring:

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

Please note that this solution only works at present if you do not need a backslash in the path (that is, if it is only the root directory). If you need a subdirectory, you will need to steal the trick I use for “SkipDeleteItems” (later in this answer) to add path metadata with thumbnails of the path to each element.

+1
source

Source: https://habr.com/ru/post/1439966/


All Articles