我在TeamCity中运行了一个主要工作的Web构建和部署配置,它基本上使用MSBuild自动将站点部署到Web服务器.默认情况下,MSDeploy在目标服务器上将所有内容设置为Readonly,并且我需要AppPool标识才能对一个文件夹具有写入权限.
我发现an article by Kevin leetham让我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,Modify" /> </sitemanifest>
这实际上看起来是正确的,最后一行是来自teh wpp.targets文件的自定义ACL.但是,当MSDeploy将其发送到目标服务器时,会发生以下情况:
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
整个事情都落在我的自定义ACL路径上,该路径使用绝对路径名而不是相对于IisWebAppName.我不明白为什么!!
请帮忙 :)
解决方法
您需要使用DefaultValue创建一个ProviderPath参数,该参数使用{param name}语法获取另一个参数的值.
这是我在another question中包含的帮助程序,它执行所有操作:
<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”(后面的答案)的技巧,为每个项目添加正则表达式转义的路径元数据.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。