I am attempting to upgrade my application like so:
It fails with the following error:
Error details:
2>Test-ServiceFabricApplicationPackage : The BuildLayout of the application in
2>C:\Users\me\AppData\Local\Temp\TestApplicationPackage_2205895293421\4myc2vpp.bdq\Debug is invalid. Code is
2>missing for service MyServicePkg.
2>At C:\Program Files\Microsoft SDKs\Service
2>Fabric\Tools\PSModule\ServiceFabricSDK\Publish-UpgradedServiceFabricApplication.ps1:135 char:38
2>+ ... nSuccess = (Test-ServiceFabricApplicationPackage $AppPkgPathToUse -Im ...
2>+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2> + CategoryInfo : InvalidOperation: (:) [Test-ServiceFabricApplicationPackage], FabricImageBuilderValidati
2> onException
2> + FullyQualifiedErrorId : TestApplicationPackageErrorId,Microsoft.ServiceFabric.Powershell.TestApplicationPackage
2>
2>Finished executing script 'Deploy-FabricApplication.ps1'.
2>Time elapsed: 00:00:40.4035177
2>The PowerShell script failed to execute.
========== Build: 1 succeeded, 0 failed, 46 up-to-date, 0 skipped ==========
========== Publish: 0 succeeded, 1 failed, 0 skipped ==========
Here are my properties for that specific project:
What am I doing wrong? What does this exception mean?
I would go with Hans Passant's comment:
The most basic mishap is that the name you used in the
ServiceManifest.xml file does not match the name of the .exe that your
project generates
It is also visible in your debug output as the build succeeded but the publish failed.
========== Build: 1 succeeded, 0 failed, 46 up-to-date, 0 skipped ==========
========== Publish: 0 succeeded, 1 failed, 0 skipped ==========
It can happen in a number of ways and most probably due to renaming of the project or renaming of the Assembly Name. If you rename the project or the Assembly Name of your project, your build executable will be according to that name. Consider the following case.
I renamed the Assembly Name from "MyService" to "MyRenamedService". So the build executable will be MyRenamedService.exe. So you have to set this in your ServiceManifest.xml.
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>MyRenamedService.exe</Program>
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>
The best way to be sure of the build executable path is to build the solution. It will show the full path of the executable in Output window.
1>------ Build started: Project: Web1, Configuration: Debug Any CPU ------
1>Web1 -> C:\.....\Application2\Web1\bin\Debug\net461\win7-x64\MyRenamedService.exe
2>------ Build started: Project: Application2, Configuration: Debug x64 ------
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Here Web1 is the Project Name I started with, MyRenamedService.exe is the build executable name (because I renamed the Assembly Name), it should be set in the ServiceManifest.xml as shown above.
At a higher level, this error happens when the folder named "Code" is missing under the ServiceFabric Project Folder during Publish (after build shows as successfully completed).
Build is the culprit here, not Publish, as Publish is expected to look for assets under
Folder Path: {{SFProjectFolder}}\pkg\Release\{{ServiceName}}
Please note that the {{ServiceName}} and "Code" is taken from the ServiceManifest.xml of the corresponding project referenced in the SF application.
ServiceManifest.xml
<ServiceManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="{{ServiceName}}" Version="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<ServiceTypes>
<StatelessServiceType ServiceTypeName="{{ServiceType}}" />
</ServiceTypes>
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>{{ServiceName}}.exe</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage
What caused the issue:
From other answers, it looks like the Build not copying the compiled assets into the right path/folder, could happen due to multiple issues.
In our case, we had changed the Configuration Manager settings for Release Configuration from AnyCPU to x64 and deleted the AnyCPU Platform setting from the solution. And for some reason, the Services.csproj still had the AnyCPU Platform setting. We ended up having the build showing as successful, but "Code" folder not being generated under Release folder.
Fix:
To fix this, we had to manually edit the .csproj and remove the PropertyGroup sections that still used "AnyCPU" like the one below:
PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
After this change, Build correctly placed the contents in the right path and Publish worked as expected.
This issue occurs when your service's executable .exe path is wrong in ServiceManifest.xml.
<CodePackage> contains .exe path in <Program> just check it out first:
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>MyServicePkgHost.exe</Program> // Important
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</EntryPoint>
</CodePackage>
Important References:
Code is missing for service error Service Fabric
https://stackoverflow.com/a/47291969/5377037
https://stackoverflow.com/a/48729871/5377037
For confirming you are not missing anything look at below two tutorials:
Service Fabric application upgrade tutorial using Visual Studio
Service Fabric application upgrade using PowerShell
Edit 1:-
Your package layout of application directory structure should be:
PS D:\temp> tree /f .\MyServicePkg
D:\TEMP\MYSERVICEPKG
│ ApplicationManifest.xml
│
└───MyServicePkgManifest
│ ServiceManifest.xml
│
├───MyServicePkg
│ MyServicePkgHost.exe
│
├───MyServicePkgConfig
│ Settings.xml
│
└───MyServicePkgData
init.dat
Error:
Why the "Code is missing for service package" occurs?
Reason:
In above directory there is missing a .bat code file from you application directory:
│
├───MyServicePkg
│ MyServicePkgHost.exe
│ MyServicePkgSetup.bat
|
So you have to add that missing file MyServicePkgSetup.bat. And following is a simple service manifest ServiceManifest.xml example that shows the SetupEntryPoint and the main EntryPoint for the service.
<?xml version="1.0" encoding="utf-8" ?>
<ServiceManifest Name="MyServiceManifest" Version="SvcManifestVersion1" xmlns="http://schemas.microsoft.com/2011/01/fabric" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Description>An example service manifest</Description>
<ServiceTypes>
<StatelessServiceType ServiceTypeName="MyServiceType" />
</ServiceTypes>
<CodePackage Name="Code" Version="1.0.0">
<SetupEntryPoint>
<ExeHost>
<Program>MyServicePkgSetup.bat</Program> // important
<WorkingFolder>CodePackage</WorkingFolder>
</ExeHost>
</SetupEntryPoint>
<EntryPoint>
<ExeHost>
<Program>MyServicePkgHost.exe</Program> // important
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.0" />
</ServiceManifest>
Configure the policy by using a local account
After you configure the service to have a setup entry point, you can change the security permissions that it runs under in the application manifest:
Under the <ServiceManifestImport> section, configure a policy to apply this principal to <SetupEntryPoint>. This tells Service Fabric that when the MyServicePkgSetup.bat file is run, it should be RunAs with administrator privileges. Given that you have not applied a policy to the main entry point, the code in MyServicePkgHost.exe runs under the system NetworkService account. This is the default account that all service entry points are run as.
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="MyApplicationType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="MyServiceTypePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides />
<Policies>
<RunAsPolicy CodePackageRef="Code" UserRef="SetupAdminUser" EntryPointType="Setup" />
</Policies>
</ServiceManifestImport>
<Principals>
<Users>
<User Name="SetupAdminUser">
<MemberOf>
<SystemGroup Name="Administrators" />
</MemberOf>
</User>
</Users>
</Principals>
</ApplicationManifest>
PS: You can verify the package structure locally through PowerShell by using the Test-ServiceFabricApplicationPackage command.
Workaround to add missing file MyServicePkgSetup.bat:
Let's now add the file MyServicePkgSetup.bat to the Visual Studio project to test the administrator privileges. In Visual Studio, right-click the service project and add a new file called MyServicePkgSetup.bat.
Next, ensure that the MyServicePkgSetup.bat file is included in the service package. By default, it is not. Select the file, right-click to get the context menu, and choose Properties. In the Properties dialog box, ensure that Copy to Output Directory is set to Copy if newer. See the following screenshot:
**File Path: ** C:\..\YourApplication\
Now open the MyServicePkgSetup.bat file and add the following commands:
REM Set a system environment variable. This requires administrator privilege
setx -m TestVariable "MyValue"
echo System TestVariable set to > out.txt
echo %TestVariable% >> out.txt
REM To delete this system variable us
REM REG delete "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v TestVariable /f
Next, build and deploy the solution to a local development cluster. After the service has started, as shown in Service Fabric Explorer, you can see that the MySetup.bat file was successful in a two ways. Open a PowerShell command prompt and type:
PS C:\ [Environment]::GetEnvironmentVariable("TestVariable","Machine")
MyValue
Then, note the name of the node where the service was deployed and started in Service Fabric Explorer--for example, Node 2. Next, navigate to the application instance work folder to find the out.txt file that shows the value of TestVariable. For example, if this service was deployed to Node 2, then you can go to this path for the MyApplicationType:
C:\SfDevCluster\Data\_App\Node.2\MyApplicationType_App\work\out.txt
Related
I have created a C# CustomActions project to use in wix to create an installer. All I have is the sample project and a sample wix project that references it. And I created an app.manifest in the C# project.
Example simple program
What I get is:
1>------ Build started: Project: SetupProject1, Configuration: Debug x86 ------
1> C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe -dDebug -d"DevEnvDir=C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\\" -dSolutionDir=C:\src\WixTest\ -dSolutionExt=.sln -dSolutionFileName=WixTest.sln -dSolutionName=WixTest -dSolutionPath=C:\src\WixTest\WixTest.sln -dConfiguration=Debug -dOutDir=bin\Debug\ -dPlatform=x86 -dProjectDir=C:\src\SetupProject1\ -dProjectExt=.wixproj -dProjectFileName=SetupProject1.wixproj -dProjectName=SetupProject1 -dProjectPath=C:\src\SetupProject1\SetupProject1.wixproj -dTargetDir=C:\src\SetupProject1\bin\Debug\ -dTargetExt=.msi -dTargetFileName=SetupProject1.msi -dTargetName=SetupProject1 -dTargetPath=C:\src\SetupProject1\bin\Debug\SetupProject1.msi -out obj\Debug\ -arch x86 -ext ..\WixTest\bin\Debug\WixTest.CA.dll Product.wxs
1>candle.exe(0,0): error CNDL0144: The extension '..\WixTest\bin\Debug\WixTest.CA.dll' could not be loaded because of the following reason: Could not load file or assembly 'file:///C:\src\WixTest\bin\Debug\WixTest.CA.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
1>Done building project "SetupProject1.wixproj" -- FAILED.
1>
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
Any idea what else I need to do?
Yes, I had a look - please try this:
Please remove the reference to WixTestCA, leave WixTest in there. You don't need a direct reference to the WixTestCA file. You need a project reference instead.
Add your company name or something (anything will do) to the attribute Manufacturer.
Add After='InstallInitialize' to the Custom element to indicate scheduling inside the InstallExecuteSequence for the custom action in question.
Here are the snippets with injected changes:
The Product element:
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="Add Company Name here" UpgradeCode="ADD-VALID-GUID-HERE">
The Custom element (custom action):
<Custom Action='LicenseInfoCustomAction' After='InstallInitialize'>NOT Installed</Custom>
EDIT 04/06/18 => Updated question with last status
So I have this working .Net 4.6 Stateful Service that currently run on my Windows Service Fabric cluster deployed on Azure.
Starting from 09/2017, I should be able to move to Linux: https://blogs.msdn.microsoft.com/azureservicefabric/2017/09/25/service-fabric-6-0-release/
So I'm trying to deploy it on Linux so I can save costs.
First things first, I've migrated all my code from .Net 4.6 to .Net Core 2.0. Now I can compile my binaries without issues. I've basically created new .Net Core projects and then moved all my source code from .Net 4.6 projects to the new .Net Core ones.
Then I've updated my Service Fabric application. I removed my previous SF services from my sfproj, then I've added my new .Net Core ones.
Looks like there is a warning (nothing on the output window though), but it's here anyway if I try to create a new empty Statful service using .Net core 2.0 through the template provided by Service Fabric Tools 2.0 (beta):
So I'm going to live with it.
On my dev machine, I've modified the 2 csproj projects that contain my Stateful services so they can run locally as Windows executables. I've used the win7-x64 runtimeIdentifier.
Running my SF cluster locally on my Windows machine is fine.
Then I've slightly changed the previous csproj files for Linux. I used the ubuntu.16.10-x64 runtimeIdentifier.
Also I've changed the ServiceManifest.xml file to target the linux-compatible binary:
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.9.6">
<EntryPoint>
<ExeHost>
<Program>entryPoint.sh</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
entryPoint.sh is a basic script that eventually executes:
dotnet $DIR/MyService.dll
Then I've successfully deployed to my secured SF Linux cluster from Visual Studio. Unfortunately I have the following errors for both my stateful services:
Error event: SourceId='System.Hosting',
Property='CodePackageActivation:Code:EntryPoint'. There was an error
during CodePackage activation.The service host terminated with exit
code:134
Looks like my binary crashes when starting. So here are my questions:
Is the approach right to deploy a C# .Net Core SF stateful service on Linux from Visual Studio?
EDIT: looking inside the LinuxsyslogVer2v0 table, I get the following error:
starthost.sh[100041]: Unhandled Exception:
System.IO.FileLoadException: Could not load file or assembly
'System.Threading.Thread, Version=4.1.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a'. The located assembly's manifest
definition does not match the assembly reference. (Exception from
HRESULT: 0x80131040)
I found the following bug report: https://github.com/dotnet/sdk/issues/1502
Unfortunately, I still get the error without using MSBuild (using dotnet deploy).
EDIT: further clarification:
My boss want me to run on Linux because starting from D1v2 machines, it's half the price compared to Windows machines (no license etc.)
My .NET Core 2.0 services successfully run on Windows. So the .NET Core port should be fine.
So, this was a real pain in the ass to get it working properly. But it works. Well, kind of.
First, Reliable Services are still in preview on Linux: https://github.com/Microsoft/service-fabric/issues/71
Full Linux support should come very soon (actually it should be available already according to the previous link...).
Now for the details about how to procede, here is some information to help others, because there is just nothing about that on Microsoft documentation and I literally lost 3 days trying to make it work.
1. Do use .NET Core 2.0 for your projects.
It is supported on Linux. On preview for now, but it works.
2. Do use the right RID for your projects.
As of today (April 2018), the right RID to use is ubuntu.16.04-x64.
Edit the csproj files of your Reliable Service projects and set the RID like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifier>ubuntu.16.04-x64</RuntimeIdentifier>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
The fun part is, you should be able to provide multiple RIDs using the RuntimeIdentifiers parameter (with a S at the end) like that:
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifiers>win7x64;ubuntu.16.04-x64</RuntimeIdentifiers>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
So you could build Windows binaries and Linux binaries at the same time.
But it simply doesn't work. When building the project from Visual Studio, I end up with the following directory only:
bin/Debug/netcoreapp2.0/
Only DLLs, no valid entry point. No win7-x64 folder, no ubuntu.16.04-x64, no nothing.
This is a bug, supposed to be fixed, but it's not (I use Visual Studio 15.6.2 all up-to-date as of today). See https://github.com/dotnet/core/issues/1039
3. You need a valid Entry Point for your service.
On Windows it's an executable file (*.exe). On Linux it's not. I ended up getting the Linux C# example and copied/pasted the entry point. https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-create-your-first-linux-application-with-csharp
So basically I now have on my ServiceManifest.xml file of each Reliable Service the following EntryPoint :
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="XXXX"
Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<!-- This is the name of your ServiceType.
This name must match the string used in RegisterServiceType call in Program.cs. -->
<StatefulServiceType ServiceTypeName="YYY" HasPersistedState="true" />
</ServiceTypes>
<!-- Code package is your service executable. -->
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>entryPoint.sh</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
entryPoint.sh is as follows:
#!/usr/bin/env bash
check_errs()
{
# Function. Parameter 1 is the return code
if [ "${1}" -ne "0" ]; then
# make our script exit with the right error code.
exit ${1}
fi
}
DIR=`dirname $0`
echo 0x3f > /proc/self/coredump_filter
source $DIR/dotnet-include.sh
dotnet $DIR/NAME_OF_YOUR_SERVICE_DLL.dll $#
check_errs $?
dotnet-include.sh is as follows:
#!/bin/bash
. /etc/os-release
linuxDistrib=$ID
if [ $linuxDistrib = "rhel" ]; then
source scl_source enable rh-dotnet20
exitCode=$?
if [ $exitCode != 0 ]; then
echo "Failed: source scl_source enable rh-dotnet20 : ExitCode: $exitCode"
exit $exitCode
fi
fi
Both are inside the PackageRoot folder. I specified for both their properties so the Build Action is "Content" and the Copy to Output Directory is "Copy always".
4. Do NOT build using MSBuild !!
Yeah it is supposed to build Linux packages too, or at least it seems so, because MSBuild is able to produce the following files when you right click on your project and click "Build":
Don't trust the apparent success of the operation, it will miserably FAIL to properly execute when deployed. Some *.so files missing and other issues. MSBuild is buggy as hell and misbehaves regarding dependencies.
See for instance this bug report: https://github.com/dotnet/sdk/issues/1502
Still not fixed after almost a year...
Or https://github.com/dotnet/core/issues/977 (got this one, too).
5. Do write some PowerShell script to build the stuff by yourself.
I ended up reinventing the wheel using the following script to build my package:
# Creating binaries for service 1
cd DIRECTORY_OF_MY_SERVICE_1
dotnet publish -c Release -r ubuntu.16.04-x64
# Creating binaries for service 2
cd ..\DIRECTORY_OF_MY_SERVICE_2
dotnet publish -c Release -r ubuntu.16.04-x64
# Creating binaries for service 3
cd ..\DIRECTORY_OF_MY_SERVICE_3
dotnet publish -c Release -r ubuntu.16.04-x64
# Copying ApplicationManifest.xml
cd ..
mkdir PKG\ServiceFabricApplication
echo F|xcopy "ServiceFabricApplication\ApplicationPackageRoot\ApplicationManifest.xml" "PKG\ServiceFabricApplication\ApplicationManifest.xml" /sy
# Copying Service1 files
mkdir "PKG\ServiceFabricApplication\Service1Pkg"
mkdir "PKG\ServiceFabricApplication\Service1Pkg\Code"
xcopy "Service1\PackageRoot\*" "PKG\ServiceFabricApplication\Service1Pkg" /sy /D
xcopy "Service1\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service1Pkg\Code" /sy
# Copying Service2 files
mkdir "PKG\ServiceFabricApplication\Service2Pkg"
mkdir "PKG\ServiceFabricApplication\Service2Pkg\Code"
xcopy "Service2\PackageRoot\*" "PKG\ServiceFabricApplication\Service2Pkg" /sy /D
xcopy "Service2\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service2Pkg\Code" /sy
# Copying Service3 files
mkdir "PKG\ServiceFabricApplication\Service3Pkg"
mkdir "PKG\ServiceFabricApplication\Service3Pkg\Code"
xcopy "Service3\PackageRoot\*" "PKG\ServiceFabricApplication\Service3Pkg" /sy /D
xcopy "Service3\bin\Release\netcoreapp2.0\ubuntu.16.04-x64\publish\*" "PKG\ServiceFabricApplication\Service3Pkg\Code" /sy
# Compresses the package
Write-host "Compressing package..."
Copy-ServiceFabricApplicationPackage -ApplicationPackagePath .\PKG\ServiceFabricApplication -CompressPackage -SkipCopy
sfproj file is a Visual Studio / MSBuild related project, so you need to build everything by yourself.
The script above produces the same content as the pkg folder created by MSBuild when building your sfproj using Visual Studio. It copies everything on a PKG folder at the root of your solution.
The package structure is detailed here: https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/service-fabric/service-fabric-package-apps.md
6. Now it's time to deploy!
At this point I didn't trusted Visual Studio anymore, so I built my own PowerShell script:
. .\ServiceFabricApplication\Scripts\Deploy-FabricApplication.ps1 -ApplicationPackagePath '.\PKG\ServiceFabricApplication' -PublishProfileFile '.\ServiceFabricApplication\PublishProfiles\Cloud.xml' -DeployOnly:$false -ApplicationParameter:#{} -UnregisterUnusedApplicationVersionsAfterUpgrade $false -OverrideUpgradeBehavior 'None' -OverwriteBehavior 'SameAppTypeAndVersion' -SkipPackageValidation:$false -ErrorAction Stop
It reuses the Deploy-FabricApplication.ps1 script provided by the Service Fabric project template inside the sfproj project. This script parses the Cloud.xml PublishProfile and deploys to your service fabric cluster.
So you specifies the rights values on both PublishProfiles/Cloud.xml and ApplicationParameters/Cloud.xml then execute the script.
It only works if you have the certificate used to secure the cluster installed on your machine, of course.
Do note the first dot '.' is important, because if you don't use it, you'll have the following error:
Get-ServiceFabricClusterManifest : Cluster connection instance is null
See https://stackoverflow.com/a/38104087/870604
Oh, and as there are bugs on the Service Fabric SDK too, you might want to shutdown your local SF cluster too...
https://github.com/Azure/service-fabric-issues/issues/821
7. Now it's time for another deception.
It simply doesn't work, the service crashes on startup. After searching hours inside the LinuxsyslogVer2v0 Azure Storage table (the log table for Linux, located in one of the two Azure Storage Accounts created automatically with the SF cluster), I found that Microsoft own Nuget Packages were buggy too.
Specifically, the Nuget package Microsoft.Azure.Devices doesn't work on version 1.6.0. An issue with a reference of a dll not found or whatever. I rollbacked to a previous version, namely 1.5.1, and it was fixed.
At this point I didn't had anymore energy to create another Github issue about that. Sorry MS, I'm not your QA team, I'm getting tired.
8. Build again using the first PowerShell script, deploy using the second PowerShell script, and you're done.
You've finally deployed C# Reliable Services using .NET Core 2.0 from Visual Studio (kind of, as it's buggy and I used PowerShell) on Windows to a Linux SF Cluster.
Now I still have issues with my ASP.NET Core service, but it will be a story for another day.
Conclusion: TL;DR
The whole thing is a mess. Bugs everywhere. In the SDK, in the tools, in some of Microsoft Nuget Packages. Awful experience. But it is supported (in preview for now) and you can make it work. Hope this post will help...
I was having similar issues, but I believe this is the issue:
In this release, .NET Core 2.0 services are only supported on Service Fabric for Windows. Full cross-platform support for .NET Core 2.0 services on Windows and Linux is coming soon.
From the Service Fabric 6.1 Release Notes
So no Linux as long as you are targeting .net core 2.0.
I have success deploy to Linux service fabric with this help
Open all the service .csproj files and update the RuntimeIdentifier as shown below
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
</PropertyGroup>
Update the ServiceManifest.xml to remove .exe extension as shown below
<CodePackage Name="Code" Version="1.0.0">
<EntryPoint>
<ExeHost>
<Program>Web1</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
See https://blogs.msdn.microsoft.com/premier_developer/2018/05/27/running-net-core-2-0-applications-in-a-linux-service-fabric-cluster-on-azure/
*Visual Studio 15.7.3
Since I needed its capability, I forked a NuGet package that was supposed to be able to enable me to process regular expressions in my build, the goal of which is to transform the .NET Framework version number into an environment variable, so that, for example, 4.7 becomes NET47. I am more than sufficiently familiar with regular expressions to make that happen, and the task runs perfectly when I call the assembly from a console program. It finds and loads the assembly, runs its Execute method, and sets the expected property values. However, when I try to run the task in a build, MSBuild reports as follows.
The "RegularExpressionMatching" task could not be loaded from the assembly RegexMatch.MSBuildTask, Version=1.0.0.7, Culture=neutral, PublicKeyToken=659f28f508fc4cd9, processorArchitecture=MSIL. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. C:\Users\DAVE\Documents\Visual Studio 2013\Projects\WizardWrx_Libs\DLLServices2\ConsoleStreamsLab\ConsoleStreamsLab_4.7\ConsoleStreamsLab_4.7.csproj 81 5 ConsoleStreamsLab_4.7
My UsingTask element is as follows.
<UsingTask TaskName="RegularExpressionMatching"
AssemblyName="RegexMatch.MSBuildTask, Version=1.0.0.7, Culture=neutral, PublicKeyToken=659f28f508fc4cd9, processorArchitecture=MSIL" />
My Target block follows.
<Target Name="SecondMatch" AfterTargets="BeforeBuild">
<Message Text="TargetFrameworkVersion = $(TargetFrameworkVersion)" Importance="high" />
<Message Text="DefineConstants = $(DefineConstants)" Importance="high" />
<RegularExpressionMatching Input="$(DefineConstants)" Pattern="^(.*)(*;NET\d{1,2})(;*.*)*$" >
<Output TaskParameter="IsMatch"
PropertyName="IsMatchJiro" />
<Output TaskParameter="Match"
PropertyName="MatchJiro" />
<Output TaskParameter="Replacement"
PropertyName="ReplacementJiro" />
</RegularExpressionMatching>
The first two messages appear in the build log, exactly as expected, and shown, next.
------ Build started: Project: ConsoleStreamsLab_4.7, Configuration: Debug Any CPU ------
Build started 2017/07/24 15:14:29.
SecondMatch:
TargetFrameworkVersion = v4.7
DefineConstants = DEBUG;TRACE
C:\Users\DAVE\Documents\Visual Studio 2013\Projects\WizardWrx_Libs\DLLServices2\ConsoleStreamsLab\ConsoleStreamsLab_4.7\ConsoleStreamsLab_4.7.csproj(81,5): error MSB4062: The "RegularExpressionMatching" task could not be loaded from the assembly RegexMatch.MSBuildTask, Version=1.0.0.7, Culture=neutral, PublicKeyToken=659f28f508fc4cd9, processorArchitecture=MSIL. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
Build FAILED.
Time Elapsed 00:00:00.00
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
Diagnostic Level Build Log is a previous attempt, run with the logging level set to Diagnostic. Though it gives a great deal more information, none of it sheds any light on the matter, so far as I can tell.
The assembly in question has a strong name, is installed into the GAC on the machine on which the build ran, and has no unusual dependencies, other than the three MSBuild assemblies.
I suspect the solution might be in the assembly references listed in the RegExMatch Solution, specifically Microsoft.Build.Utilities.v4.0, since I am unsure how that correlates with the build engine that runs in Visual Studio 2013, which reports itself as version 12 (although that may refer only to the version of Visual Studio with which it ships).
I would really like to get this working, so that I can do this task the data driven way, and eliminate hard coded settings. Once I have a proof of concept, I'll be delighted as well to submit a pull request to the original author.
I'll have my eyes open for good suggestions.
Did you import the project of the extensions? I haven't used the specific extensions you used, but when I used the MSBuildExtensions I had to add a set of lines to the effect of:
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
Only after this line was present was I able to acess the targets and use the extensions.
I'm trying to host WebAPI service on local ServiceFabric cluster. However, I'm unable to start even a simple Web Api template provided by VS2017.
I did the following:
I prepared the environment: https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-get-started
I created a new project in Visual Studio, choosing "Service Fabric Application", and "Stateless Web API" service template
When I build it, and click run, it tries to deploy it but I get the following error:
Screen1
And the output is:
2>Copying application to image store... 2>Copy application
package succeeded 2>Registering application type...
2>Register-ServiceFabricApplicationType : Operation timed out.
2>At C:\Program Files\Microsoft SDKs\Service
Fabric\Tools\PSModule\ServiceFabricS
2>DK\Publish-NewServiceFabricApplication.ps1:251 char:9 2>+
Register-ServiceFabricApplicationType -ApplicationPathInImage ...
2>+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2>
+ CategoryInfo : OperationTimeout: (Microsoft.Servi...usterConnection:ClusterConnection)
[Register-ServiceFabricApplicationType], TimeoutException 2> +
FullyQualifiedErrorId :
RegisterApplicationTypeErrorId,Microsoft.Service 2>
Fabric.Powershell.RegisterApplicationType 2>Finished executing
script 'Deploy-FabricApplication.ps1'. 2>Time elapsed:
00:02:01.7559509 2>The PowerShell script failed to execute.
========== Build: 1 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
========== Deploy: 0 succeeded, 1 failed, 0 skipped ==========
The interesting part is that when I choose basic "Stateless Service" template in Visual Studio, it works just fine. The problem I have is related to Web Api service on SF. My assumption is that the Web Api project has to write some additional info somewhere on the disk but does not have access to that path.
I tried reinstalling SF and SF SDK but with no results. I'm running VS2017 as an Administrator.
Any help greatly appreciated.
Environment: Visual Studio 2013 Premium, Win7Ultimate, CodeCoverage.exe
Goal: Code Coverage Report that excludes test project code to later be converted to a .coveragexml for reporting to SonarQube 5.1.
Annoyance I wouldn't even know of this parse error without adding the /verbose switch to the command. My only indication of a failure was the .coverage file was no longer being generated when I added the /config switch.
File Works in VS2013 IDE: MyProject.runsettings file provides the expected output using "Analyze Code Coverage" in the IDE.
Menu: Test | Test Settings | Select Test Settings File... MyProject.runsettings
Menu: Test | Analyze Code Coverage | All Tests
Attempting to run the CodeCoverage.exe file to generate code coverage for my tests I can't seem to use ANY *.runsettings files without getting an error:
"Error: Failed to parse configuration file <configfile>.runsettings"
Path Definitions:
codeCoveragePath = C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Dynamic Code Coverage Tools
vstestpath = C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow
myProjectOutputPath = assume correct since I get results when not using /config switch
Run Command receiving Error (assume paths are correct):
Note: I'm not showing with /verbose switch since I shouldn't be using it under working conditions
%codeCoveragePath%\CodeCoverage.exe collect /config:MyProject.runsettings /output:CoverageOutput.coverage %vstestpath%\vstest.console.exe %myProjectOutputPath%\MyClass.Tests.Unit.dll
Exe Works if I DON'T use the /config option If I remove the /config:MyProject.runsettings from the run command, I get a full report that includes the test project, but that let's me know the rest of the command is correct, it just doesn't like the runsettings file.
I've tried using the following examples:
Visual Studio 2013 runsettings Template file WITHOUT modification
MSDN's sample file
Completed blank file, no content: error
File with only the xml declaration: error
File with only RunSettings Node declared: error
I've even used the Troubleshooting tips from MSDN, too: no help.
MyProject.runsettings file:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>
<ModulePaths>
<Exclude>
<ModulePath>.*\.Tests\.Unit\.dll$</ModulePath>
</Exclude>
</ModulePaths>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
The file seems to be correct based on the fact that the IDE will use it and generate the correct output in the "Code Coverage Results" window by only reporting the MyClass code and not any MyClass.Tests.Unit code.
I'm at the point that I think it is the CodeCoverage.exe command line doesn't like the /config option or it is using a different xml schema.
Update
Works gives the output I want, just can't specify file location for next step
%vstestpath%\vstest.console.exe /Settings:MySettings.runsettings %myProjectOutputPath%\MyClass.Tests.Unit.dll
Doesn't Work Gives exact opposite output I want (only test.dll coverage in the report).
%codeCoveragePath%\CodeCoverage.exe collect /output:CoverageOutput.coverage %vstestpath%\vstest.console.exe /Settings:MySettings.runsettings %myProjectOutputPath%\MyClass.Tests.Unit.dll
Still looking for an answer.
I believe you need to specify the runsettings file at the back of the vstest.console.exe using the /Settings: flag (as opposed to the config flag of the CodeCoverage.exe).
So that your command becomes:
%codeCoveragePath%\CodeCoverage.exe collect
/output:CoverageOutput.coverage %vstestpath%\vstest.console.exe
%myProjectOutputPath%\MyClass.Tests.Unit.dll
/Settings:MyProject.runsettings
I was having the same problem and found your question when searching for some info on my error. My assumption had been also that the config file format was the same as the .runsettings used by vstest.console.exe but from the parse error after adding /verbose I then suspected it was a different format so had a look to see if there was a default config for CodeCoverage.exe to see what it looked like, and I did find one at:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Dynamic Code Coverage Tools\CodeCoverage.config
And the format appears to just be the inner <CodeCoverage> part of the .runsettings format
I have now got filtering to work but needed to copy over all the filter items from the default config as they now don't get loaded, so I ended up using a config like the following:
<CodeCoverage>
<ModulePaths>
<Exclude>
<ModulePath>.*\\unittests.dll</ModulePath>
</Exclude>
</ModulePaths>
<Sources>
<Exclude>
<!--extracted from default CodeCoverage.config -->
<Source>.*\\atlmfc\\.*</Source>
<Source>.*\\vctools\\.*</Source>
<Source>.*\\public\\sdk\\.*</Source>
<Source>.*\\externalapis\\.*</Source>
<Source>.*\\microsoft sdks\\.*</Source>
<Source>.*\\vc\\include\\.*</Source>
</Exclude>
</Sources>
<Functions>
<Exclude>
<!--extracted from default CodeCoverage.config -->
<Function>^std::.*</Function>
<Function>^ATL::.*</Function>
<Function>.*::__GetTestMethodInfo.*</Function>
<Function>.*__CxxPureMSILEntry.*</Function>
<Function>^Microsoft::VisualStudio::CppCodeCoverageFramework::.*</Function>
<Function>^Microsoft::VisualStudio::CppUnitTestFramework::.*</Function>
<Function>.*::YOU_CAN_ONLY_DESIGNATE_ONE_.*</Function>
</Exclude>
</Functions>
</CodeCoverage>
and command line:
CodeCoverage collect /output:coverage.dat /config:coverage.settings vstest.console unitTests.dll /Logger:trx /Settings:test.runsettings
Okay, Here comes the HACK!!!!
Basic steps:
Find and delete all *.coverage files
Run vstest command WITHOUT [codecoverage.exe collect] wrapper
Find the new *.coverage files and send to [codecoverage.exe analyze] command
Details
I updated the build.proj file I've been using to execute all this to do the Basic steps:
<PropertyGroup>
<SqCodeCoverageResultsFile>VisualStudio.coveragexml</SqCodeCoverageResultsFile>
</PropertyGroup>
<Target Name="BuildTestAssemblyList"
BeforeTargets="RunAllTestsWithCodeCoverageAndConvertToXmlOutput">
<CreateItem Include="**\*.Tests.Unit.dll">
<Output TaskParameter="Include" ItemName="TestAssemblies" />
</CreateItem>
</Target>
<Target Name="BuildCoverageFileList"
BeforeTargets="RunAllTestsWithCodeCoverageAndConvertToXmlOutput">
<CreateItem Include="**\*.coverage">
<Output TaskParameter="Include" ItemName="CoverageFiles" />
</CreateItem>
</Target>
<Target Name="RunAllTestsWithCodeCoverageAndConvertToXmlOutput">
<Delete Condition="Exists($(SqCodeCoverageResultsFile))" Files="$(SqCodeCoverageResultsFile)" />
<Delete Files="#(CoverageFiles)" />
<Exec Command=""$(VsTestExecutable)" /EnableCodeCoverage /Settings:MyProject.runsettings /inIsolation /logger:trx #(TestAssemblies->'"%(FullPath)"',' ') " />
<CreateItem Include="**\*.coverage">
<Output TaskParameter="Include" ItemName="NewCoverageFiles" />
</CreateItem>
<Exec Command=""$(VsCodeCoverageExecutable)" analyze /output:"$(SqCodeCoverageResultsFile)" #(NewCoverageFiles->'"%(FullPath)"',' ') " />
</Target>`
Now running the CodeCoverage.exe analyze command with those found *.coverage files will now output to the same filename I was trying to achieve before and get the results I wanted.
MSBuild.SonarQube.Runner.exe gets what it wants, I have the results I want, and the world can start to revolve again =)
Improvement: I could use a CustomTask and search for the perfect or most recent or whatever logic you can think of for that correct single file so I wouldn't have to delete all my other *.coverage files. I could, but I didn't because this is supposed to be run on a build server that shouldn't have that kind of history laying around anyways in my opinion.