Thursday, January 4, 2018

DotNet Core script case sensitivity on Linux systems, like AWS AMI

I recently ran into an issue where I was unable to deploy a DotNet Core 1.0 application in AWS using their CodeStar / CodePipeline / CodeDeploy / CodeBuild tooling.  The REST service started off as a simple demo .Net 1.x ASP.Net that was generated as a demo in AWS CodeStar.  I converted the source code, build and deployment components to DotNet 2.0. It worked great.

Problem

The service build / deployment broke in AWS when I added Swagger endpoint documentation that included information from C# XML documentation generated and stored an XML file. Startup failed saying they couldn't find the <ServiceName>.xml documenation file. This manifested as a build failure in CodePiepline/CodeDeploy.

  • bin\Release\netcoreapp2.0\TokenService.xml not found
    

Builds ran and deployed fine on my local machine in Debug and Release modes.

Cause

Microsoft's recommended "dotnet publish" command line may generate conflicting path with csproj files when using manipulating and consuming files sitting on a file system that is case sensitive.  File locations inside scripts and properties may contain conflicting capitalization. This is no problem on a case-insensitive files systems like NTFS.  It can be a problem on Linux systems..

I found this when running DotNet Core 2.x applications on an AWS on Ubuntu while enabling Swagger.  C# applications can generate XML documentation from the method and class API comments. Swagger can consume this XML in order to augment the default swagger comment behavior. That XML file must be in the right location with the right cased path.

XML Documentation file is generated at compile time and packaged with the service.  That file is only visible if all the components have the same path/case expectation.
  "/object_root/Release/netcore20/foo.xml" != "/object_root/release/netcore20/foo.xml"
.Net Microsoft standardized configurations to include "Debug" and "Production", not "debug" and "production". From the csproj file

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DocumentationFile>bin\Release\netcoreapp2.0\TokenService.xml</DocumentationFile>
  </PropertyGroup>

The following build command comes from AWS CodeStar templates and several wikipages. Note: the _lower case_ 'r' of the -o option.

  • dotnet publish -c release -o <output> <csproj>
  • creates
  • release\netcoreapp2.0\foo.xml
The configuration should be Release with a _capital R_.
  • dotnet publish -c Release -o ./build_output TokenService/TokenService.csproj
  • creates
  • Release\netcoreapp2.0\foo.xml

Sample  buildspec.yml for DotNet Core 2.0 with sSagger

Here is the updated buildspec file.  Note the dotnet publish output parameter

version: 0.2
phases:  pre_build:    commands:      - echo Using tooling dotnet version `dotnet --version`
      - echo Restore started on `date`
      - dotnet restore TokenService/TokenService.csproj
  build:    commands:      - echo Build started on `date`
      - dotnet publish -c Release -o ./build_output TokenService/TokenService.csproj
artifacts:  files:    - TokenService/build_output/**/*
    - scripts/**/*
    - appspec.yml

Code

You can find a .Net 2.0 compatible project that deploys on AWS Linux on this FreemanSoft GitNHub  repository.  
  • See the buildspec.yml for the right dotnet publish syntax. 
  • See the install_dotnetcore script to see how to instal .Net Core 2.0 on a Linux AMI

Create 2018 Jan 04

No comments:

Post a Comment