tech.guitarrapc.cóm

Technical updates

.NET Core でgitなどSCM情報をCIで埋め込んでアプリケーションに表示する方法と選択

開発中、リリースのいずれにおいても「今どのバージョンなのか」という情報は重要な情報です。 とはいえ、実際に埋め込みたいのはバージョンというより「ソースコード」とくに「コミット」と連動する情報、加えて「ビルド」と紐づく情報もほしいでしょう。 どのようにすれば実現できるか、これを.NET Coreをベースに考えてみましょう。

真新しいことはなく、よく昔からあるやつを今ならどうやるかというメモです。 前回の知識があれば簡単です。

目次

TL;DR;

  • shallow-clone が不要なアプリケーションでは、GitVersioning がおすすめです。(お任せできる)
  • shallow-clone が必要なアプリケーションでは、GitInfo がおすすめです。(お任せできる)
  • git tag をベースにCIでバージョンを埋め込む方法もあります。(csproj の調整やビルドでの埋め込みが必要)
  • ビルド時にスクリプトを実行して実行時にjsonを読み込みDIすることももちろん可能です。(生成スクリプト、型セーフにあつかうためのクラス、DIが必要)
  • 独自にAssetmbly Attribute を埋めることもできます。(csprojとの調整が必要)

GitHub

この記事の内容は、GitHub で公開しています。 実コードのサンプルが見たい場合に利用してください。

github.com

なぜSCM情報を埋め込みたいのか

CI/CD を組むと、継続的にアプリケーションが展開されるようになります。 継続的にアプリケーションが展開されるとき、SCM / CI / CD / Application の4か所を通りますが、普段意識するのは末端となるSCMとApplicationの2か所でしょう。

結果、「Git commit をしたらアプリケーションが展開される。動いているアプリケーションをみたらGit Commit情報が知りたい。」となるでしょう。 これにより、今動いているアプリケーションが、どのコミットによるものなのか/PRによるものなのかを、「Git、Build、Deployの順にたどることなく、アプリケーションをみるだけでGitにとぶことが可能」になります。

途中のCI情報、CD情報も知りたいかもしれませんがここでは主題ではないので省略します。*1

.NET Framework におけるSCM情報の埋め込み方法

Golangを含め、各種言語にはその言語でやりやすいやり方があります。 .NET Core の場合を考える前に、過去、.NET Framework ではどうやっていたのかを振り返って、考え方の遷移をみてみます。

.NET Framework においては、 Properties/AssemblyInfo.cs が常に存在したためここへの直接的なアプローチが多く使われていました。

しかしこのようにAssemblyInfo.cs を手で触るのは避けたいでしょう。*2

gozuk16.hatenablog.com

そこで、Visual Studio ワークフローとも相性がいい .csproj に MSBuild task でフックする方法がよく利用されていたように思います。*3

nowfromhome.com

また、柔軟に埋め込み内容を調整できるためPreBuild でスクリプトを回して AssemblyInfo.cs に書き込む方法もよく使われていました。*4

blog.shibayan.jp

埋め込みはAssemblyInfo.cs へのテンプレーティングにすぎないので、T4という手もありますがあまり使われてないように思います。*5

qiita.com

もちろん、適当は public static なプロパティを用意しておいて sed をかませるのでもいいでしょう。

いずれにしても、「各種方法で特定の値をAssemblyInfo.cs に埋め込み、ビルドを通してAssembly の InformationalVersion に埋め込む、アプリの実行時はアセンブリ自身から情報を拾っていた」というのが大筋の流れです。

これらは .NET Core でも筋は同じですが、微妙に事情が変わります。

.NET Core でSCM情報をどこに仕込むと楽なのか

.NET Core で大きく変わったことは2つあります。

1つは.csproj が SDKベースのフォーマットになったことです。 前回の記事で見た通りProperties/AssemblyInfo.cs がビルド時に自動生成されるようになったため、バージョンを埋め込む時に今までとは違った考慮が必要になりました。 何も考えずに.NET Frameworkと同様にAssetblyInfo.cs を生成しようとすると属性の重複やあと勝ちにより意図しない挙動が生じます。

tech.guitarrapc.com

もう1つの転換が、WebHost/GenericHost と Configuration Provider と DI のフレームワーク化です。 .NET Coreでは、.NET Frameworkでつかわれていた app.config の仕組みから、xml/json/引数/環境変数 など各種読込先を個別に読み込む仕組みに変わりました。 また、WebHost/GenericHost により任意のファイルからタイプセーフにクラスにマッピングし、DIで各種処理で差し込むことも容易にできるようになっています。

以上の2点から、.NET Core でバージョンを仕込むには2つの方法がよく利用されています。

  • AssemblyInfo に差し込まれる仕組みをフックする
  • jsonなどを生成して、DIを経由してランタイムで読み込む

これを前提情報に、バージョンの埋め込みを見ていきましょう。

GitVersioningを使ったGit情報埋め込み

Git情報を埋め込んだり、アプリのバージョンを自動でやってほしいときは、Nerdbank.GitVersioning が使いやすいでしょう。

項目 情報
GitHub AArnott/Nerdbank.GitVersioning
アセンブリバージョンの生成方法 自動(Git Height) + CLI引数
SCM 情報の取得 可能
バージョンフォーマットの指定 version.json
shallow clone での利用 ×

このライブラリは、.NET 以外にも Node でも使え、VSIXでも埋め込みに利用できます。

このライブラリはとても使いやすいのですが、2つ注意がいります。 git height を利用しているため、実行時に全コミット履歴を辿ります。そのため、shallow clone と共存が不可能です。shallow clone を使っているプロジェクトでは利用できません。

github.com

バージョンのハンドルは、csproj のVersionではなく version.json による定義からの自動生成に任せましょう。

Nerdbank.GitVersioning/versionJson.md at master · AArnott/Nerdbank.GitVersioning

利用方法が微妙にわかりにくいため、使うにあたっての注意と.NET Core での利用方法をサンプルプロジェクトを使って説明します。

github.com

NuGet パッケージを使ってビルド時に自動的にバージョンを埋め込む

.NET Core で使う場合、nbgvという .NET Core Global Tool とNuGet Package の2つの方法があります。

ただ「毎ビルドで自動的にバージョンを埋め込みたいだけ」ならNuGet Packageで十分です。 CLIはもう少し複雑な操作を自動化するのに使います。

dotnet add package Nerdbank.GitVersioning

www.nuget.org

あとは一度ビルドすると、アプリケーションからThisAssembly というstatic class 経由でアセンブリに埋め込まれたGit Version情報を実行時に参照可能になります。 確認しましょう。

gist.github.com

実行結果です。

AssemblyConfiguration: Debug
AssemblyFileVersion: 0.0.10.14829
AssemblyInformationalVersion: 0.0.10+ed39ef6655
AssemblyName: NerdGitVersioningConsole
AssemblyTitle: NerdGitVersioningConsole
AssemblyVersion: 0.0.0.0
GitCommitId: ed39ef6655ebc044d8925f8c62aa09a4ceb0ea8c
RootNamespace: NerdGitVersioningConsole

バージョン書式は Version.json で調整できるので、リファレンスみつつ適当にやるかお任せするといいでしょう。 あんまり頑張ろうとするとつらくなります。

ほかにもいくつかのSaaS 型CIのビルド情報からバージョンを埋める機能もありますが、CircleCi はありません。

Nerdbank.GitVersioning/cloudbuild.md at master · AArnott/Nerdbank.GitVersioning

nbgv CLI を使ってバージョンを埋め込む

CLIを使うと、プロジェクトにNuGet Packageを適用することと、リリース用ブランチを切ってコミットさせることが簡単に自動化できます。 CIでGitVersioningを動的に導入してバージョンをはかせるときはCLIが使いやすいでしょう。 もしプロジェクトにNuGetパッケージを追加してコミットしてよく、リリースブランチ戦略も取ってないならCLIは不要です。

CLI は .NET Global Tool なので、dotnet sdk が入っていればコマンド1つで CLIを利用可能になります。

dotnet tool install -g nbgv

www.nuget.org

CLIを使って、GitVersioning をプロジェクトに導入するには install コマンドを利用します。

nbgv install

Directory.Build.props があるとき、ここにパッケージをadd として追加するので影響範囲が広がるため注意してください。 個別のプロジェクトフォルダでCLIを使ってinstallして影響範囲を狭めるといいでしょう。

あとは普通に dotnet build をすると、assemblyinfo.cs の生成をフックして、ビルドされたアセンブリにバージョンを埋め込んでくれます。 バージョンのフォーマットは、version.jsonの定義に従うので必要に応じてビルド前に生成しましょう。

CLIを使うと、リリースブランチ戦略が簡単に自動化できます。 よくある、reease/v1.x.xv1.0.0 のようなブランチを切ってリリースしていく場合、prepare-release を使うことで自動的にブランチを作りコミットしてくれます。

nbgv prepare-release

バージョン自動生成の裏側

裏側を説明します。NuGet Package を追加すると、Nerdbank.GitVersioning.Tasks というmsbuild task が追加されます。 このタスクによって、AssemblyInfo.cs ではなく ASSEMBLYNAME.AssemblyInfo.csASSEMBLYNAME.Version.cs をビルド前にobjフォルダに生成するようになります。

この中で重要なのが、ASSEMBLYNAME.Version.csです。中に ThisAssembly という静的クラスが書かれていることがわかります。

gist.github.com

GitInfoを使ったGit情報埋め込み

ただGit情報を埋め込みたいだけの場合、GitInfo はNerdbank.GitVersioningよりもシンプルにやりたいことをやってくれます。

項目 情報
GitHub kzu/GitInfo: Git and SemVer Info from MSBuild, C# and VB
アセンブリバージョンの生成方法 Assetmbly attribute で自分で指定可能
SCM 情報の取得 可能
バージョンフォーマットの指定 GitInfo.txt
shallow clone での利用

Gitの情報を拾ってきて埋めるだけなので、シンプルにできているのが最大のメリットです。

シンプルに利用する

ただ Git情報を参照するだけなら NuGet Package を導入するだけでできます。

dotnet add package Nerdbank.GitInfo

サンプルプロジェクトで見てみましょう。

github.com

NuGet パッケージの導入後、一度ビルドすると ThisAssembly経由でGitバージョン情報にアクセスできます。

gist.github.com

出力結果です。

Branch: master
BaseTag:
Commit: ed39ef6
Commits: 10
IsDirty: True
Sha: ed39ef6655ebc044d8925f8c62aa09a4ceb0ea8c
Tag:
Major: 0
Minor: 0
Patch: 0
DashLabel:
Label:
Major: 0
Minor: 0
Patch: 10
Source: Default

特徴的なのが、リポジトリのコミット総数を埋め込んでおり SemVer の Patchバージョンにこれを埋め込みます。 また、ファイルバージョンは何もしません。

バージョンの埋め込みも行う

.NET Core で AssemblyInfo.cs はビルド時に自動生成されるようになりました。 しかしこの自動生成自体を止めたり、特定の属性の出力を止めることはできることは前回の記事でみました。

tech.guitarrapc.com

これを利用して、GitInfo のThisAssembly を使ってアセンブリバージョンを埋め込んでみましょう。 AssemblyVersion、AssemblyFileVersion、AssemblyInformationalVersion の3つのバージョンがありますが、それぞれにバージョンを指定します。

gist.github.com

csproj で重複する属性を AssetmblyInfo に自動生成しないようにすることでビルドが通るようになります。

gist.github.com

また、GitInfo はこのままでは FileVersion は 0.0.0 なので、GitInfo.txt をプロジェクトの同一階層においてバージョンを指定します。

0.0.1

実行してみると意図したとおりにバージョンが書き込まれていることがわかります。

Branch: master
BaseTag:
Commit: ed39ef6
Commits: 1
IsDirty: True
Sha: ed39ef6655ebc044d8925f8c62aa09a4ceb0ea8c
Tag:
Major: 0
Minor: 0
Patch: 1
DashLabel:
Label:
Major: 0
Minor: 0
Patch: 2
Source: File
assemblyVersion: 0.0.1.0
fileVersion: 0.0.2
productVersion: 0.0.1+ed39ef6

Source が File になっており、GitInfo が読み込まれたことがわかります。

git tag をベースに埋め込む

この方法は、アセンブリやNuGet パッケージのバージョンを指定するのに最も簡素な方法の1つです。 SCMだとちょっと埋め込み時に工夫がいるので素朴すぎ感があります。

実際に使っているリポジトリを見てみましょう。

github.com

csproj に Versionプロパティ要素を用意しておくことで、dotnet build でビルドするときに値を差し込むことができます。

gist.github.com

あとは、ビルド時にプロパティを指定しましょう。

dotnet build -c Release -p:Version=${CIRCLE_TAG}

このようにすることで、Version や Git SCM の情報を任意のプロパティに埋めることができます。 CircleCI の場合は、CIRCLE_SHA1 環境変数でSHA1 を取り出せます。

Using Environment Variables - CircleCI

スクリプトでjsonを生成してDIする

csproj に頼らずバージョンを指定したいときには、.NET Core がjson など任意のファイルをコンフィグとして読み込み、DIで指せることが利用できます。 流れは単純です。

  • scm情報をCIでjsonに吐き出し
  • ビルド時にjsonを一緒に配置
  • アプリ実行時にDI
  • DI経由で呼び出し

scm情報をCIでjsonに吐き出し

プロジェクトに次のSet-GitAppVersion.ps1スクリプトをContentRoot直下に突っ込みます。 これは、CI でスクリプトを実行してSCMの情報をもったjsonを作るコマンドを並べただけです。 仮にPowerShell で書きましたがbashでもcsx でも pythonでもjson 作ればなんでもokです。

gist.github.com

これをビルド時に実行すればversion,json がプロジェクト直下に配置されます。

ビルド時にjsonを一緒に配置

csproj をいじって、version.jsonあったときは、ビルド時にコピーするようにします。

gist.github.com

普段は version.json はなくていいので、.gitignoreにしておくといいでしょう。

version.json

アプリ実行時にクラスにバインドする

型セーフに扱うため、マッピングするAppVersionクラスと、バインドを任せるAppVersionServiceを作ります。

gist.github.com

あとは、ConfigureServicesメソッドのラムダ内や Startup.cs でDIに登録することで View や各箇所で呼び出すことができます。

gist.github.com

DI経由で呼び出し

View に Razor で埋め込む場合は、@InjectでDIからとってくることができます。

gist.github.com

あとは、meta の html5で紹介された data-* を使ったり

    <meta name="application-name" content="Nextscape.Holojector.AssetGenerator.Web" data-version="@shortHash" data-deployment="@lastUpdate" />

json ブロックを吐き出してもいいでしょう。

    <script id="version" type="application/json">
        {
        "ShortHash": "@shortHash",
        "LastUpdate": "@lastUpdate"
        }

手間がかかるので幾分素朴すぎ感があります。 別にこんなことをしたくないという。

*1:この記事の内容を応用してすぐに組めるので

*2:手はやりたくない筆頭

*3:いわゆるド定番

*4:スクリプト使いたくないですね

*5:このためにT4したくないのは当然だと思います

.NET Core で AssemblyInfo.cs の生成を制御する

C# のアセンブリ情報は AssemblyInfo.cs によって制御されています。 .NET Core でいくぶん取り扱いが変わったものの基本は一緒です。

たびたび忘れるので、どのように取り扱いが変わったのか制御方法をメモしておきます。

目次

TL;DR

  • .NET Core で AssemblyInfo.cs はビルド時に自動生成されるようになりました
  • csprojにGenerateAssemblyInfoを指定することで自動生成自体を止めたり、GenerateAssemblyXxxxxAttributeを指定することで特定属性の出力を止めることができます
  • 出力を上書きたいときは、上書きたい属性だけ制御するようにして予期せぬ副作用は回避しましょう

Microsoft.NET.GenerateAssemblyInfo.targets

AssemblyInfo は、.NET Framework まではProperties/AssemblyInfo.cs として存在していましたが、.NET Core SDK ベースのcsproj ではビルド時に自動生成されるようになりました。

この自動生成を制御しているMSBuildのタスク Microsoft.NET.GenerateAssemblyInfo.targets を見つつどのように行うか見ていきましょう。

sdk/Microsoft.NET.GenerateAssemblyInfo.targets at master · dotnet/sdk

AssemblyInfo の自動生成をなぜ制御するのか

自前でAssemblyInfoを生成しようとしたときに、属性が重複してビルドできなくなるためです。

例えば、.NET Core の適当なプロジェクトを作って次のようにアセンブリのバージョンを任意の値で制御しようとするとエラーが起こります。

gist.github.com

エラーは次の通りです。

Error CS0579 Duplicate 'System.Reflection.AssemblyVersionAttribute' attribute

このような時に、AssemblyInfo の出力を制御したくなります。

AssemblyInfoの自動生成を止める

dotnet core のプロジェクトでビルドをすると、obj フォルダの中にASSEMBLYNAME.AssemblyInfo.cs が自動生成されます。 ASSEMBLYNAME は、デフォルトではプロジェクト名ですがご存知の通り指定もできます。(ここでは省きます)

先ほどの Microsoft.NET.GenerateAssemblyInfo.targets から、次の属性で制御されていることがわかります。

<PropertyGroup Condition="'$(GenerateAssemblyInfo)' == 'true'">

AssemblyInfo の自動生成を止めたいプロジェクトのcsproj に次の要素を書くことで、objに生成されなくなります。

<PropertyGroup>
  <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

例えば先ほどのConsole アプリのcsproj を編集してみましょう。(上:編集前 Before.csproj / 下:編集後 After.csproj)

gist.github.com

これでAssebly属性の重複によるビルドエラーが解消して、ビルドができるようになりました。 先ほどまであったConsoleApp2.AssemblyInfo.cs が obj フォルダに生成されなくなったことが確認できます。

obj の中を見るとConsoleApp2.AssemblyInfo.cs がないことが分かる

ただし、AssemblyInfo の自動生成を止めると副作用が大きいため推奨しません。

特に、ASP.NET Core や .NET Core で UserSecrets を使っている場合は、UserSecretsが機能しなくなります。 これは、UserSecrets が実行時にsecret のパスを参照するときにSecret Id はAssemblyInfo にビルド時に埋め込むようにしており、自動生成を止めるとUserSecrets の Id も参照できなくなるためです。

AssemblyInfo の特定の属性の生成を止める

先ほどのようにただバージョンを指定したものにするなら、AssemblyInfoは生成するけど、特定の属性をとめるほうが副作用がありません。 これは先ほどの Microsoft.NET.GenerateAssemblyInfo.targets から、次の属性で制御されていることがわかります。

gist.github.com

例えば、今回のようなAssemblyVersion 属性の重複なら、次の要素をcsprojに追加しましょう。

<PropertyGroup>
  <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
</PropertyGroup>

これでAssemblyInfo の生成自体をとめることなくビルドできるようになります。 obj に自動生成された ConsoleApp2.AssemblyInfo.cs を見てみると、意図したとおり属性で指定したバージョンが埋め込まれていることがわかります。

gist.github.com

SQL Server Docker Image のCU12以降でDBがクラッシュする件

SQL Serverは Dockerで動かせるので、いちいちSQL Server をインストールせずともローカル開発をスムーズに回すことができます。

hub.docker.com

そんな SQL Server on Docker ですが、macOS ではホストのDBファイルをボリュームマウントができない制約があります。

Mounting a volume does not work on Docker for Mac

一方で、Windows ではホストのDBファイルをボリュームマウントできるため永続化させたいときとかに便利です。

さて、今回の記事はWindows環境でホストのDBをコンテナでマウントするとクラッシュする件が起こっていることについてです。

目次

TL;DR

CU12*1 以降でホストのDBファイルをボリュームマウントで渡していると、SQL Serverがクラッシュします。

latest でも発生しており、ホストのDBをボリュームマウントする場合は、CU11 に落とすのが暫定対処になりそう。

Issue

CU 12 で問題は発覚しました。

github.com

CU13以降、現在の latest では、このCU13 のクラッシュログが確認できます。

github.com

再現してみよう

とりあえず手元で再現すれば逃げ道も見つかります。試しましょう。

2017-latest (2017-latest-ubuntu)

現在の最新イメージでホストのボリュームをマウントしない場合は、SQL Server が起動できていることがわかります。

docker run -it -e ACCEPT_EULA=Y mcr.microsoft.com/mssql/server:2017-latest

ログを開く

2019-04-26 03:07:27.52 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2019-04-26 03:07:27.56 Server      Did not find an existing master data file /var/opt/mssql/data/master.mdf, copying the missing default master and other system database files. If you have moved the database location, but not moved the database files, startup may fail. To repair: shutdown SQL Server, move the master database to configured location, and restart.
2019-04-26 03:07:27.56 Server      Setup step is copying system data file 'C:\templatedata\mastlog.ldf' to '/var/opt/mssql/data/mastlog.ldf'.
2019-04-26 03:07:27.57 Server      Setup step is copying system data file 'C:\templatedata\model.mdf' to '/var/opt/mssql/data/model.mdf'.
2019-04-26 03:07:27.58 Server      Setup step is copying system data file 'C:\templatedata\modellog.ldf' to '/var/opt/mssql/data/modellog.ldf'.
2019-04-26 03:07:27.59 Server      Setup step is copying system data file 'C:\templatedata\msdbdata.mdf' to '/var/opt/mssql/data/msdbdata.mdf'.
2019-04-26 03:07:27.61 Server      Setup step is copying system data file 'C:\templatedata\msdblog.ldf' to '/var/opt/mssql/data/msdblog.ldf'.
2019-04-26 03:07:27.68 Server      Microsoft SQL Server 2017 (RTM-CU14) (KB4484710) - 14.0.3076.1 (X64)
        Mar 12 2019 19:29:19
        Copyright (C) 2017 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 16.04.6 LTS)
2019-04-26 03:07:27.68 Server      UTC adjustment: 0:00
2019-04-26 03:07:27.68 Server      (c) Microsoft Corporation.
2019-04-26 03:07:27.68 Server      All rights reserved.
2019-04-26 03:07:27.68 Server      Server process ID is 28.
2019-04-26 03:07:27.69 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:07:27.69 Server      Registry startup parameters:
         -d /var/opt/mssql/data/master.mdf
         -l /var/opt/mssql/data/mastlog.ldf
         -e /var/opt/mssql/log/errorlog
2019-04-26 03:07:27.69 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:07:27.69 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:07:27.70 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:07:27.70 Server      Using conventional memory in the memory manager.
2019-04-26 03:07:27.84 Server      Buffer pool extension is already disabled. No action is necessary.
2019-04-26 03:07:27.94 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:07:27.94 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:07:27.94 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:07:27.98 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:07:27.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an
informational message only. No user action is required.
2019-04-26 03:07:27.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:07:27.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:07:28.02 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
ForceFlush is enabled for this instance.
2019-04-26 03:07:28.03 Server      Query Store settings initialized with enabled = 1,
2019-04-26 03:07:28.03 Server      Software Usage Metrics is disabled.
2019-04-26 03:07:28.04 spid6s      Starting up database 'master'.
ForceFlush feature is enabled for log durability.
2019-04-26 03:07:28.16 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:07:28.27 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:07:28.27 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:28.30 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:28.33 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:28.35 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:28.36 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:28.37 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:28.38 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:28.47 Server      Failed to verify the Authenticode signature of 'C:\binn\secforwarder.dll'. Signature verification of SQL Server DLLs will be skipped. Genuine copies of SQL Server are signed. Failure to verify the Authenticode signature might indicate that this is not an authentic release of SQL Server. Install a genuine copy of SQL Server or contact customer support.
2019-04-26 03:07:28.58 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:07:28.58 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:07:28.59 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:07:28.62 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:07:28.64 spid6s      Server name is '4200ec551fc5'. This is an informational message only. No user action is required.
2019-04-26 03:07:28.65 spid19s     Password policy update was successful.
2019-04-26 03:07:28.66 spid22s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:07:28.66 spid6s      Starting up database 'msdb'.
2019-04-26 03:07:28.67 spid22s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:07:28.67 spid11s     Starting up database 'mssqlsystemresource'.
2019-04-26 03:07:28.67 spid11s     The resource database build version is 14.00.3076. This is an informational message only. No user action is required.
2019-04-26 03:07:28.70 spid11s     Starting up database 'model'.
2019-04-26 03:07:28.85 spid19s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:07:28.86 spid19s     Server is listening on [ 'any' <ipv6> 1433].
2019-04-26 03:07:28.86 spid19s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:07:28.86 spid11s     The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:07:28.87 Server      Server is listening on [ ::1 <ipv6> 1434].
2019-04-26 03:07:28.87 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:07:28.87 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:07:28.87 spid19s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:07:28.87 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:07:28.99 spid11s     Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:07:28.99 spid11s     Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:29.00 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:07:29.00 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:07:29.06 spid11s     Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:29.10 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:07:29.10 spid11s     Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:29.12 spid11s     Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:29.12 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:07:29.13 spid11s     Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:29.13 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:07:29.14 spid11s     Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:29.15 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:07:29.16 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:07:29.16 spid11s     Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:29.17 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:07:29.29 spid11s     Polybase feature disabled.
2019-04-26 03:07:29.29 spid11s     Clearing tempdb database.
2019-04-26 03:07:29.63 spid11s     Starting up database 'tempdb'.
2019-04-26 03:07:29.82 spid11s     The tempdb database has 1 data file(s).
2019-04-26 03:07:29.83 spid22s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:07:29.83 spid22s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:07:29.84 spid22s     Service Broker manager has started.
2019-04-26 03:07:29.96 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:07:29.98 spid24s     The default language (LCID 0) has been set for engine and full-text services.
2019-04-26 03:07:33.03 spid35s     The activated proc '[dbo].[sp_syspolicy_events_reader]' running on queue 'msdb.dbo.syspolicy_event_queue' output the following:  'Transaction (Process ID 35) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction

では、適当にフォルダを掘ってからDBフォルダにマウントしましょう。

mkdir c:\db
docker run -it -e ACCEPT_EULA=Y -v C:\db:/var/opt/mssql mcr.microsoft.com/mssql/server:2017-latest-ubuntu

見事にクラッシュしています。

This program has encountered a fatal error and cannot continue running at Fri Apr 26 03:14:04 2019
The following diagnostic information is available:

       Reason: 0x00000006
       Status: 0x40000015
      Message: Kernel bug check
      Address: 0x6a844180
   Parameters: 0x10861f680
   Stacktrace: 000000006a92fc73 000000006a8441db 000000006a831422
               000000006a83fe62 000000006a92e08a 000000006a92cb8d
               000000006a96c0d2 000000006acac000 000000006ac38000
               000000006ac40000 0000000000000001
      Process: 7 - sqlservr
       Thread: 11 (application thread 0x4)
  Instance Id: 72388ba8-dd88-4469-b1fe-c4794d04ff54
     Crash Id: 3593f479-5b4f-4ef6-ad74-b70a3bda2756
  Build stamp: b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253
 Distribution: Ubuntu 16.04.6 LTS
   Processors: 2
 Total Memory: 2076528640 bytes
    Timestamp: Fri Apr 26 03:14:04 2019

Ubuntu 16.04.6 LTS
Capturing core dump and information to /var/opt/mssql/log...
dmesg: read kernel buffer failed: Operation not permitted
No journal files were found.
No journal files were found.
Attempting to capture a dump with paldumper
WARNING: Capture attempt failure detected
Attempting to capture a filtered dump with paldumper
WARNING: Attempt to capture dump failed.  Reference /var/opt/mssql/log/core.sqlservr.7.temp/log/paldumper-debug.log for details
Attempting to capture a dump with gdb
WARNING: Unable to capture crash dump with GDB. You may need to
allow ptrace debugging, enable the CAP_SYS_PTRACE capability, or
run as root.

クラッシュログ置いておきます。

crash.txt

This program has encountered a fatal error and cannot continue running at Fri Apr 26 03:40:08 2019
The following diagnostic information is available:

       Reason: 0x00000006
       Status: 0x40000015
      Message: Kernel bug check
      Address: 0x6c244180
   Parameters: 0x10861f680
   Stacktrace: 000000006c32fc73 000000006c2441db 000000006c231422 
               000000006c23fe62 000000006c32e08a 000000006c32cb8d 
               000000006c36c0d2 000000006c6ac000 000000006c638000 
               000000006c640000 0000000000000001 
      Process: 7 - sqlservr
       Thread: 11 (application thread 0x4)
  Instance Id: e467da02-a594-4124-93cb-c8eb2415c65a
     Crash Id: e751eea3-120c-448b-92c5-dc0b370c783d
  Build stamp: b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253
 Distribution: Ubuntu 16.04.6 LTS
   Processors: 2
 Total Memory: 2076528640 bytes
    Timestamp: Fri Apr 26 03:40:08 2019

crash.json

{
    "reason": "0x00000006",
    "processName": "sqlservr",
    "pid": "7",
    "instanceId": "e467da02-a594-4124-93cb-c8eb2415c65a",
    "crashId": "e751eea3-120c-448b-92c5-dc0b370c783d",
    "threadId": "11",
    "libosThreadId": "0x4",
    "buildStamp": "b2ce95e3a6684060d1d3bb1264841a1a8fc1d501ed6d1cfdb89cfcdde8048253",
    "status": "0x40000015",
    "message": "Kernel bug check",
    "address": "0x6c244180",
    "parameters": [
        {
            "value": "0x41"
        },
        {
            "value": "0xffffffffc0000034"
        },
        {
            "value": "0x5"
        },
        {
            "value": "0x0"
        },
        {
            "value": "0x0"
        }
    ],
    "libosStack": [
        "0x000000006c32fc73",
        "0x000000006c2441db",
        "0x000000006c231422",
        "0x000000006c23fe62",
        "0x000000006c32e08a",
        "0x000000006c32cb8d",
        "0x000000006c36c0d2",
        "0x000000006c6ac000",
        "0x000000006c638000",
        "0x000000006c640000",
        "0x0000000000000001"
    ],
    "last_errno": "2",
    "last_errno_text": "No such file or directory",
    "distribution": "Ubuntu 16.04.6 LTS",
    "processors": "2",
    "total_memory": "2076528640",
    "timestamp": "Fri Apr 26 03:40:08 2019"
}

No such file or directory.....

2017-CU11-ubuntu

CU11 まで落とすとマウントできています。

mkdir c:\db
docker run -it -e ACCEPT_EULA=Y -v C:\db:/var/opt/mssql mcr.microsoft.com/mssql/server:2017-CU11-ubuntu

ログを開く

2019-04-26 03:18:07.29 Server      Setup step is copying system data file 'C:\templatedata\master.mdf' to '/var/opt/mssql/data/master.mdf'.
2019-04-26 03:18:08.13 Server      Did not find an existing master data file /var/opt/mssql/data/master.mdf, copying the missing default master and other system database files. If you have moved the database location, but not moved the database files, startup may fail. To repair: shutdown SQL Server, move the master database to configured location, and restart.
2019-04-26 03:18:08.15 Server      Setup step is copying system data file 'C:\templatedata\mastlog.ldf' to '/var/opt/mssql/data/mastlog.ldf'.
2019-04-26 03:18:08.19 Server      Setup step is copying system data file 'C:\templatedata\model.mdf' to '/var/opt/mssql/data/model.mdf'.
2019-04-26 03:18:08.34 Server      Setup step is copying system data file 'C:\templatedata\modellog.ldf' to '/var/opt/mssql/data/modellog.ldf'.
2019-04-26 03:18:08.49 Server      Setup step is copying system data file 'C:\templatedata\msdbdata.mdf' to '/var/opt/mssql/data/msdbdata.mdf'.
2019-04-26 03:18:08.69 Server      Setup step is copying system data file 'C:\templatedata\msdblog.ldf' to '/var/opt/mssql/data/msdblog.ldf'.
2019-04-26 03:18:09.69 Server      Microsoft SQL Server 2017 (RTM-CU11) (KB4462262) - 14.0.3038.14 (X64)
        Sep 14 2018 13:53:44
        Copyright (C) 2017 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
2019-04-26 03:18:09.70 Server      UTC adjustment: 0:00
2019-04-26 03:18:09.70 Server      (c) Microsoft Corporation.
2019-04-26 03:18:09.70 Server      All rights reserved.
2019-04-26 03:18:09.70 Server      Server process ID is 4120.
2019-04-26 03:18:09.70 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:18:09.70 Server      Registry startup parameters:
         -d /var/opt/mssql/data/master.mdf
         -l /var/opt/mssql/data/mastlog.ldf
         -e /var/opt/mssql/log/errorlog
2019-04-26 03:18:09.72 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:18:09.72 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      Using conventional memory in the memory manager.
2019-04-26 03:18:12.56 Server      Buffer pool extension is already disabled. No action is necessary.
2019-04-26 03:18:13.80 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:18:13.80 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:18:13.81 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:18:13.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an
informational message only. No user action is required.
2019-04-26 03:18:13.99 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:18:13.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:18:13.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:18:14.24 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
ForceFlush is enabled for this instance.
2019-04-26 03:18:14.24 Server      Query Store settings initialized with enabled = 1,
2019-04-26 03:18:14.25 spid6s      Starting up database 'master'.
2019-04-26 03:18:14.28 Server      Software Usage Metrics is disabled.
ForceFlush feature is enabled for log durability.
2019-04-26 03:18:15.76 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:18:16.63 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:18:16.63 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:16.65 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:16.82 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:16.84 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:16.87 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:18.14 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.47 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:18:18.48 spid18s     Password policy update was successful.
2019-04-26 03:18:18.49 spid6s      Server name is 'f16aca2a7c35'. This is an informational message only. No user action is required.
2019-04-26 03:18:18.49 spid21s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid21s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid8s      Starting up database 'mssqlsystemresource'.
2019-04-26 03:18:18.50 spid6s      Starting up database 'msdb'.
2019-04-26 03:18:18.51 spid8s      The resource database build version is 14.00.3038. This is an informational message only. No user action is required.
2019-04-26 03:18:18.53 spid8s      Starting up database 'model'.
2019-04-26 03:18:20.73 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:18:20.77 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:18:20.77 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.78 spid8s      The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:18:20.81 spid8s      Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:18:20.81 spid8s      Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.82 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid8s      Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.86 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.86 spid8s      Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.87 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.87 spid8s      Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.88 spid8s      Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.88 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid8s      Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:20.92 spid8s      Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:21.05 spid8s      Polybase feature disabled.
2019-04-26 03:18:21.05 spid8s      Clearing tempdb database.
2019-04-26 03:18:24.70 spid18s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:18:24.73 spid18s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:18:24.74 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:18:24.74 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:18:24.75 spid18s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:18:25.93 spid8s      Starting up database 'tempdb'.
2019-04-26 03:18:27.55 spid8s      The tempdb database has 1 data file(s).
2019-04-26 03:18:27.55 spid21s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:18:27.56 spid21s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:18:27.57 spid21s     Service Broker manager has started.
2019-04-26 03:18:27.68 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:18:33.21 spid10s     The default language (LCID 0) has been set for engine and full-text services.

対処方法

CU11 まで落とすと、問題は発生しません。 Microsoftの反応がないので、どうするのか悩ましいですがいったんCU11 で固定しておくとよさそうです。

余談

自分でDockerfile 書いてSQL Server (Linux) をインストールして利用という手もあります。

が、試しに CU12 のイメージをもとにDockerfile を書くと面白いログが出ています。(CU12+ からapt-get で sql-server を入れてないため)

The following additional packages will be installed:

mssql-server

gist.github.com

どんな対応がいいのかしらの反応が待ち遠しいですね。

エラーログ

おいておきます。

2019-04-26 03:18:09.69 Server      Microsoft SQL Server 2017 (RTM-CU11) (KB4462262) - 14.0.3038.14 (X64) 
    Sep 14 2018 13:53:44 
    Copyright (C) 2017 Microsoft Corporation
    Developer Edition (64-bit) on Linux (Ubuntu 16.04.5 LTS)
2019-04-26 03:18:09.70 Server      UTC adjustment: 0:00
2019-04-26 03:18:09.70 Server      (c) Microsoft Corporation.
2019-04-26 03:18:09.70 Server      All rights reserved.
2019-04-26 03:18:09.70 Server      Server process ID is 4120.
2019-04-26 03:18:09.70 Server      Logging SQL Server messages in file '/var/opt/mssql/log/errorlog'.
2019-04-26 03:18:09.70 Server      Registry startup parameters: 
     -d /var/opt/mssql/data/master.mdf
     -l /var/opt/mssql/data/mastlog.ldf
     -e /var/opt/mssql/log/errorlog
2019-04-26 03:18:09.72 Server      SQL Server detected 1 sockets with 1 cores per socket and 2 logical processors per socket, 2 total logical processors; using 2 logical processors based on SQL Server licensing. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
2019-04-26 03:18:09.72 Server      Detected 1584 MB of RAM. This is an informational message; no user action is required.
2019-04-26 03:18:09.72 Server      Using conventional memory in the memory manager.
2019-04-26 03:18:12.56 Server      Buffer pool extension is already disabled. No action is necessary. 
2019-04-26 03:18:13.80 Server      InitializeExternalUserGroupSid failed. Implied authentication will be disabled.
2019-04-26 03:18:13.80 Server      Implied authentication manager initialization failed. Implied authentication will be disabled.
2019-04-26 03:18:13.81 Server      Successfully initialized the TLS configuration. Allowed TLS protocol versions are ['1.0 1.1 1.2']. Allowed TLS ciphers are ['ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA'].
2019-04-26 03:18:13.98 Server      Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.
2019-04-26 03:18:13.99 Server      The maximum number of dedicated administrator connections for this instance is '1'
2019-04-26 03:18:13.99 Server      Using dynamic lock allocation.  Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node.  This is an informational message only.  No user action is required.
2019-04-26 03:18:13.99 Server      In-Memory OLTP initialized on lowend machine.
2019-04-26 03:18:14.24 Server      Database Instant File Initialization: enabled. For security and performance considerations see the topic 'Database Instant File Initialization' in SQL Server Books Online. This is an informational message only. No user action is required.
2019-04-26 03:18:14.25 spid6s      Starting up database 'master'.
2019-04-26 03:18:14.24 Server      Query Store settings initialized with enabled = 1, 
2019-04-26 03:18:14.28 Server      Software Usage Metrics is disabled.
2019-04-26 03:18:15.76 spid6s      The tail of the log for database master is being rewritten to match the new sector size of 4096 bytes.  3072 bytes at offset 418816 in file /var/opt/mssql/data/mastlog.ldf will be written.
2019-04-26 03:18:16.63 spid6s      Converting database 'master' from version 862 to the current version 869.
2019-04-26 03:18:16.63 spid6s      Database 'master' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:16.65 spid6s      Database 'master' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:16.82 spid6s      Database 'master' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:16.84 spid6s      Database 'master' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:16.85 spid6s      Database 'master' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:16.87 spid6s      Database 'master' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:18.14 spid6s      Resource governor reconfiguration succeeded.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit is starting the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.14 spid6s      SQL Server Audit has started the audits. This is an informational message. No user action is required.
2019-04-26 03:18:18.47 spid6s      SQL Trace ID 1 was started by login "sa".
2019-04-26 03:18:18.48 spid18s     Password policy update was successful.
2019-04-26 03:18:18.49 spid6s      Server name is 'f16aca2a7c35'. This is an informational message only. No user action is required.
2019-04-26 03:18:18.49 spid21s     Always On: The availability replica manager is starting. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid21s     Always On: The availability replica manager is waiting for the instance of SQL Server to allow client connections. This is an informational message only. No user action is required.
2019-04-26 03:18:18.50 spid8s      Starting up database 'mssqlsystemresource'.
2019-04-26 03:18:18.50 spid6s      Starting up database 'msdb'.
2019-04-26 03:18:18.51 spid8s      The resource database build version is 14.00.3038. This is an informational message only. No user action is required.
2019-04-26 03:18:18.53 spid8s      Starting up database 'model'.
2019-04-26 03:18:20.73 spid6s      The tail of the log for database msdb is being rewritten to match the new sector size of 4096 bytes.  512 bytes at offset 306688 in file /var/opt/mssql/data/MSDBLog.ldf will be written.
2019-04-26 03:18:20.77 spid6s      Converting database 'msdb' from version 862 to the current version 869.
2019-04-26 03:18:20.77 spid6s      Database 'msdb' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.78 spid8s      The tail of the log for database model is being rewritten to match the new sector size of 4096 bytes.  2048 bytes at offset 75776 in file /var/opt/mssql/data/modellog.ldf will be written.
2019-04-26 03:18:20.81 spid8s      Converting database 'model' from version 862 to the current version 869.
2019-04-26 03:18:20.81 spid8s      Database 'model' running the upgrade step from version 862 to version 863.
2019-04-26 03:18:20.82 spid6s      Database 'msdb' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid8s      Database 'model' running the upgrade step from version 863 to version 864.
2019-04-26 03:18:20.84 spid6s      Database 'msdb' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.86 spid6s      Database 'msdb' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.86 spid8s      Database 'model' running the upgrade step from version 864 to version 865.
2019-04-26 03:18:20.87 spid6s      Database 'msdb' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.87 spid8s      Database 'model' running the upgrade step from version 865 to version 866.
2019-04-26 03:18:20.88 spid8s      Database 'model' running the upgrade step from version 866 to version 867.
2019-04-26 03:18:20.88 spid6s      Database 'msdb' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid8s      Database 'model' running the upgrade step from version 867 to version 868.
2019-04-26 03:18:20.90 spid6s      Database 'msdb' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:20.92 spid8s      Database 'model' running the upgrade step from version 868 to version 869.
2019-04-26 03:18:21.05 spid8s      Polybase feature disabled.
2019-04-26 03:18:21.05 spid8s      Clearing tempdb database.
2019-04-26 03:18:24.70 spid18s     A self-generated certificate was successfully loaded for encryption.
2019-04-26 03:18:24.73 spid18s     Server is listening on [ 'any' <ipv4> 1433].
2019-04-26 03:18:24.74 Server      Server is listening on [ 127.0.0.1 <ipv4> 1434].
2019-04-26 03:18:24.74 Server      Dedicated admin connection support was established for listening locally on port 1434.
2019-04-26 03:18:24.75 spid18s     SQL Server is now ready for client connections. This is an informational message; no user action is required.
2019-04-26 03:18:25.93 spid8s      Starting up database 'tempdb'.
2019-04-26 03:18:27.55 spid8s      The tempdb database has 1 data file(s).
2019-04-26 03:18:27.55 spid21s     The Service Broker endpoint is in disabled or stopped state.
2019-04-26 03:18:27.56 spid21s     The Database Mirroring endpoint is in disabled or stopped state.
2019-04-26 03:18:27.57 spid21s     Service Broker manager has started.
2019-04-26 03:18:27.68 spid6s      Recovery is complete. This is an informational message only. No user action is required.
2019-04-26 03:18:33.21 spid10s     The default language (LCID 0) has been set for engine and full-text services.
2019-04-26 03:20:54.61 spid6s      Always On: The availability replica manager is going offline because SQL Server is shutting down. This is an informational message only. No user action is required.
2019-04-26 03:20:54.61 spid6s      SQL Server shutdown due to Ctrl-C or Ctrl-Break signal. This is an informational message only. No user action is required.
2019-04-26 03:20:54.61 spid6s      SQL Trace was stopped due to server shutdown. Trace ID = '1'. This is an informational message only; no user action is required.

*1:CU = Cumulative Update - a periodic release that includes bug fixes, security fixes, and occasionally a small feature.

.NET Core Global Tools のインストールとアップグレードを状態に応じて行う

.NET Core Global Tools は.NET Core SDKがインストールされている環境でdotnet系cliツールをlist/install/upgrade/uninstall を行う仕組みです。

docs.microsoft.com

この仕組みがでたことで、少なくとも dotnet core製のCLIツールの配布はnugetを経由することで統合的に行うことができるようになりました。 おおむねnpmと同様の感覚で使えるため、npmが入っておらず dotnet だけがはいった環境で便利です。

例えば、CI環境では.NET Coreビルド時に .NET Core SDK は入っているけどnpmはない、など特定のシーンで強力に機能します。 さて、今回はこのインストール、アップグレードに関してみてみましょう。

目次

インストールとアップグレードをまとめて行いたい

.NET Core Global Toolsは、インストールに dotnet tool install、アップグレードに dotnet tool upgrade とそれぞれ別のコマンドを用います。 dockerなど、環境が使い捨ての場合はこれで十分なのでシンプルさはとてもいいことです。

一方で、すでにツールxxxx がインストールされている環境で dotnet tool install --global xxxx を行うと exit code 1 が生じ、インストールされていない環境で dotnet tool upgrade xxxx を行うと exit code 1 が生じます。 つまり、ホスト環境など「すでにツールがインストールされている環境」に対してツールのインストールを保証するシーンではひと手間加える必要があります。

ではUnityBuildRunnerを例にサクッと書いてみましょう。

www.nuget.org

サンプルはリポジトリに置いておきます。

github.com

cmd (Windows環境)

もし bash が使えないgowなども利用できないWindows環境の場合、batで保証するように書いてみましょう。 よくあるコマンドの存在を確認して切り替えれば十分でしょう。

dotnet tool list -g | findstr unitybuildrunner 
if ('%errorlevel%' == '1') ( 
    dotnet tool install --global UnityBuildRunner --version 1.1.5 
) else ( 
    dotnet tool update --global UnityBuildRunner 
) 

bash

linux 環境では command を使って探したいところですが、dotnet 自体は成功してしまうので list から grep してお茶を濁します。

if dotnet tool list -g | grep unitybuildrunner; 
then 
    dotnet tool update --global UnityBuildRunner 
else 
    dotnet tool install --global UnityBuildRunner --version 1.1.5 
fi 

まとめ

dotnet コマンドで保証してくれてもいい気もしつつ、まぁ仕方ない。

Ref

解消するっぽい....? 未インストール状態で、dotnet tool update -g unitybuildrunner は今のところだめっぽい。

github.com

AzureDevOpsPipeline/Azure DevOps Pipeline で docker build と Azure Container Repository への push を行う

Azure Pipeline を使っているとタスクによせたくなるのですが、あんまりそういうのもアレなのでほどほどにというのはもうちょっと言われてもいい気がします。 Docker はその最たる例で コマンドで3行で済むようなものがDockerタスクを使うといたずらに時間を取られる傾向にあります。

今回は Azure DevOps Pipeline でDocker ビルドを行って、Azure Container Repository に push する流れを見てみましょう。 Azure DevOps Pipeline を使っていないなら、これでやるメリットはアカウント統合程度で特にない感じです。(アカウント統合も統合できていない感がつよい)

目次

[:contents:]

TL;DR

ビルドマシンは hosted が楽でよい。 docker build は、dockerタスクではなく docker コマンドでやるほうがいい docker push は、docker タスクを使って認証を透過的に行おう。

何をDockerで動かすの

ASP.NET Core 2.2 を対象にdockerで動かしてみましょう。 例えばAzure Container Instance で動かすのもいいのです。 しかし、container じゃなくてもAzure Web Apps for Linux にデプロイすれば たいがいはいいのでWebアプリのdocker展開はポータビリティをどこまで担保したいか、どう動かしたいかの相談なのでほどほどに。

Azure DevOps Pipeline の Docker タスク

Docker Module は、0 と 1と2があります。

0 を利用するのがおすすめです。

Docker タスク0.*

1 は妙な挙動をして不安定なためお勧めしません。

Dockerタスク 1.*

2 は、コンセプトが変わっててACRで使うならあんまりいらなさそう。というか、余計な手間が増えてて微妙。

Dockerタスク2.*

ローカルでの docker build

なにはともあれlocal で通しておきましょう。 これがCIで通るようにします。

適当にこんな構成とします。 ASPNETCOREにcsprojの名前を、YOUR_PROJECT_DIR にプロジェクトのフォルダ名を指定しておきます。

.
└ src
  └ YOUR_PROJECT_DIR 
      ├ Dockerfile
      └ ASPNETCORE.csproj

Dockerfileはこのような感じになるかと思います。

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src/YOUR_PROJECT_DIR
COPY ["YOUR_PROJECT_DIR/ASPNETCORE.csproj", "ASPNETCORE.csproj"]
RUN dotnet restore "ASPNETCORE.csproj"
WORKDIR /src
COPY . .
WORKDIR /src/YOUR_PROJECT_DIR
ARG conf="Debug"
RUN dotnet build "ASPNETCORE.csproj" -c $conf -o /app
RUN dotnet publish "ASPNETCORE.csproj" -c $conf -o /app

FROM base AS final
WORKDIR /app
COPY --from=build /app .
ENTRYPOINT ["dotnet", "ASPNETCORE.dll"]

あとは実行時に ASPNETCORE_ENVIRONMENT を Development | Staging | Production で指定すれば挙動が切り替わるのでokですね。

docker build

特にWindows系のhosted|private agent がそうですが、build をする場合、Dockerタスクではなく docker コマンドをたたくほうが安定します。 dockerタスクで行おうとすると、docker build中にイメージが見つかったり見つからなかったり、COPYが実行できたりできなかったり構成を変えていないのに実行ごとに挙動が変わりました。(これでDockerfile や設定がおかしいかと思って試行錯誤で数時間消費した)

variables:
  BuildConfiguration: Debug
  DockerImageName: ASPNETCORE
  DockerFile: YOUR_PROJECT_DIR/Dockerfile

steps:
- bash: 'docker build -t youraspnetcoreregistry.azurecr.io/$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) -t $(Registry).azurecr.io/$(DockerImageName):latest -f YOUR_PROJECT_DIR/Dockerfile .'
  displayName: 'docker build'

これでビルドが実行できます。 ACRに挙げるにあたって、ビルドごとにバージョンが一意に特定できる必要があるので、git hash + build id で毎ビルドで一意にしています。

docker push

push は簡単です。 local でいうところの、docker login しておいて docker push です。 ただし、CIでやるに伴ってレジストリのログインを認証情報を出さずに透過的に行いたいでしょう。

docker@0 タスク を使うと ACRへの認証情報を事前に解決しておけるので便利です。

先ほど docker build で指定した tag を指定してpush してあげましょう。 この時、ACRを対象にしている場合、ACRのアドレス "youraspnetcoreregistry.azurecr.io" 部分は自動的に解決されるため、tagで指定する必要がありません。docker build でyouraspnetcoreregistry.azurecr.io/$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) と指定した場合、$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId) でokです。(.... なんと余計なことを)

- task: Docker@0
  displayName: 'Push an image'
  inputs:
    azureSubscription: YOUR_SUBSCRIPTION
    azureContainerRegistry: '{"loginServer":"youraspnetcoreregistry.azurecr.io", "id" : "/subscriptions/abcdefg-1234-abcd-56789ghijklmn/resourceGroups/AWESOME-RESOURCE/providers/Microsoft.ContainerRegistry/registries/youraspnetcoreregistry"}'
    action: 'Push an image'
    imageName: '$(DockerImageName):$(Build.SourceVersion)_$(Build.BuildId)'
    includeLatestTag: true

これで無事にdocker build -> push ができるでしょう。