.NET Core のNugetパッケージと中身のDLLのバージョンにGitのコミットIDを含める

だいぶ前に、.NET Framework でAssemblyInfoをいじってファイルバージョンを自動採番するというのをやったのですが、

gozuk16.hatenablog.com

最近は、.NET Coreのプロジェクトが始まってやり方が色々違うし、どうやらJavaでやってたようにGitのコミットIDを入れられそうだというので試してみました。 あと、最近はNexusリポジトリにNugetパッケージをアップしているのですが、開発中にファイル名が同じだとキャッシュが更新されないことがあったのでビルドのたびにファイル名を変えたいというのがあります。 合わせて中身のDllの製品バージョンも一緒にできるといいなーと。

tech.guitarrapc.com

ここのサイトでは、GitVersioningとGitInfoが紹介されていたのでまずはシンプルそうなGitInfoを試してみました。

プロジェクトを新規作成

>dotnet new console -o assemblyInfoTest

cd assemblyInfoTest

>dotnet run
Hello World!

プロジェクトにGitInfoを追加

www.nuget.org

>dotnet add package GitInfo --version 2.0.20

早速Gitの情報を取得してみます。

using System;
using System.Diagnostics;
using System.Reflection;

namespace assemblyInfoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine($"GitBranch: {ThisAssembly.Git.Branch}");
            Console.WriteLine($"GitCommit: {ThisAssembly.Git.Commit}");
            Console.WriteLine($"GitSha: {ThisAssembly.Git.Sha}");
            Console.WriteLine($"GitBaseVersionMajor: {ThisAssembly.Git.BaseVersion.Major}");
            Console.WriteLine($"GitBaseVersionMinor: {ThisAssembly.Git.BaseVersion.Minor}");
            Console.WriteLine($"GitBaseVersionPatch: {ThisAssembly.Git.BaseVersion.Patch}");
            Console.WriteLine($"GitCommits: {ThisAssembly.Git.Commits}");
            Console.WriteLine($"GitTag: {ThisAssembly.Git.Tag}");
            Console.WriteLine($"GitBaseTag: {ThisAssembly.Git.BaseTag}");
            Console.WriteLine($"GitSemVerMajor: {ThisAssembly.Git.SemVer.Major}");
            Console.WriteLine($"GitSemVerMinor: {ThisAssembly.Git.SemVer.Minor}");
            Console.WriteLine($"GitSemVerPatch: {ThisAssembly.Git.SemVer.Patch}");
            Console.WriteLine($"GitSemVerLabel: {ThisAssembly.Git.SemVer.Label}");
            Console.WriteLine($"GitSemVerDashLabel: {ThisAssembly.Git.SemVer.DashLabel}");
            Console.WriteLine($"GitSemVerSource: {ThisAssembly.Git.SemVer.Source}");
            Console.WriteLine($"GitIsDirty: {ThisAssembly.Git.IsDirty}");

            var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
            var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
            var productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
            Console.WriteLine($"assemblyVersion: {assemblyVersion}");
            Console.WriteLine($"fileVersion: {fileVersion}");
            Console.WriteLine($"productVersion: {productVersion}");
        }
    }
}
C:\home\gozu\projects\assemblyInfoTest>dotnet run
Hello World!
GitBranch: master
GitCommit: 5ac94b0
GitSha: 5ac94b013eef929d3b8a932247966bd5f9a87952
GitBaseVersionMajor: 0
GitBaseVersionMinor: 0
GitBaseVersionPatch: 0
GitCommits: 2
GitTag:
GitBaseTag:
GitSemVerMajor: 0
GitSemVerMinor: 0
GitSemVerPatch: 2
GitSemVerLabel:
GitSemVerDashLabel:
GitSemVerSource: Default
GitIsDirty: True
assemblyVersion: 1.0.0.0
fileVersion: 1.0.0.0
productVersion: 1.0.0

簡単に取れました。

Git情報を埋め込んでみる

以下を追加しました。

[assembly: AssemblyVersion(ThisAssembly.Git.BaseVersion.Major + "." + ThisAssembly.Git.BaseVersion.Minor + ThisAssembly.Git.BaseVersion.Patch)]
[assembly: AssemblyFileVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch)]
[assembly: AssemblyInformationalVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch + "-" +
    ThisAssembly.Git.Branch + "+" + ThisAssembly.Git.Commit)]
>dotnet run
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(12,12): error CS0579: System.Reflection.AssemblyFileVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(13,12): error CS0579: System.Reflection.AssemblyInformationalVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]
obj\Debug\netcoreapp2.2\assemblyInfoTest.AssemblyInfo.cs(16,12): error CS0579: System.Reflection.AssemblyVersionAttribute' 属性が重複しています。 [C:\home\gozu\projects\assemblyInfoTest\assemblyInfoTest.csproj]

ビルドに失敗しました。ビルド エラーを修正して、もう一度実行してください。

.NET CoreだとAssemblyInfo.csが生成されるので書き換えたいプロパティの生成を抑制する必要があるらしい。

csprojに以下を追加しました。

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
    <GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
    <GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
  </PropertyGroup>
>dotnet run
Hello World!
GitBranch: master
GitCommit: 37fdbb4
GitSha: 37fdbb48f4c47b29089f6dd0ce36178c21500861
GitBaseVersionMajor: 0
GitBaseVersionMinor: 0
GitBaseVersionPatch: 0
GitCommits: 3
GitTag:
GitBaseTag:
GitSemVerMajor: 0
GitSemVerMinor: 0
GitSemVerPatch: 3
GitSemVerLabel:
GitSemVerDashLabel:
GitSemVerSource: Default
GitIsDirty: False
assemblyVersion: 0.0.0.0
fileVersion: 0.0.3
productVersion: 0.0.3-master+37fdbb4

おー、出来た!

CIで外部から指定できるように

想定ではJenkinsでnupkgのファイル名とDllの製品バージョンをビルドごとに一意なバージョンにするなので、GitのコミットIDを付加する方向で行きます。

外部から指定できるようにcsprojに Version を定義しておきます。 1.0.0としてますが書き換わるので気にしない。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
    <!--GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute-->
    <!--GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute-->
    <Version>1.0.0</Version>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="GitInfo" Version="2.0.20">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>

</Project>

コードの方も調整します。 FileVersionだけは入れておこうかという感じです。

using System;
using System.Diagnostics;
using System.Reflection;

//[assembly: AssemblyVersion(ThisAssembly.Git.BaseVersion.Major + "." + ThisAssembly.Git.BaseVersion.Minor + ThisAssembly.Git.BaseVersion.Patch)]
[assembly: AssemblyFileVersion(ThisAssembly.Git.SemVer.Major + "." + ThisAssembly.Git.SemVer.Minor + "." + ThisAssembly.Git.SemVer.Patch)]
//[assembly: AssemblyInformationalVersion("1.0.0" + "-alpha." + ThisAssembly.Git.Commit)]

namespace assemblyInfoTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Console.WriteLine($"GitBranch: {ThisAssembly.Git.Branch}");
            Console.WriteLine($"GitCommit: {ThisAssembly.Git.Commit}");
            Console.WriteLine($"GitSha: {ThisAssembly.Git.Sha}");
            Console.WriteLine($"GitBaseVersionMajor: {ThisAssembly.Git.BaseVersion.Major}");
            Console.WriteLine($"GitBaseVersionMinor: {ThisAssembly.Git.BaseVersion.Minor}");
            Console.WriteLine($"GitBaseVersionPatch: {ThisAssembly.Git.BaseVersion.Patch}");
            Console.WriteLine($"GitCommits: {ThisAssembly.Git.Commits}");
            Console.WriteLine($"GitTag: {ThisAssembly.Git.Tag}");
            Console.WriteLine($"GitBaseTag: {ThisAssembly.Git.BaseTag}");
            Console.WriteLine($"GitSemVerMajor: {ThisAssembly.Git.SemVer.Major}");
            Console.WriteLine($"GitSemVerMinor: {ThisAssembly.Git.SemVer.Minor}");
            Console.WriteLine($"GitSemVerPatch: {ThisAssembly.Git.SemVer.Patch}");
            Console.WriteLine($"GitSemVerLabel: {ThisAssembly.Git.SemVer.Label}");
            Console.WriteLine($"GitSemVerDashLabel: {ThisAssembly.Git.SemVer.DashLabel}");
            Console.WriteLine($"GitSemVerSource: {ThisAssembly.Git.SemVer.Source}");
            Console.WriteLine($"GitIsDirty: {ThisAssembly.Git.IsDirty}");

            var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
            var fileVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
            var productVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion;
            Console.WriteLine($"assemblyVersion: {assemblyVersion}");
            Console.WriteLine($"fileVersion: {fileVersion}");
            Console.WriteLine($"productVersion: {productVersion}");

        }
    }
}

Jenkinsfileで以下のようにdotnetコマンドを実行してビルドとパッケージングをします。

bat """chcp 65001

for /f "usebackq tokens=*" %%a in (`git rev-parse --short HEAD`) do @set GIT_COMMIT=%%a
for /f "usebackq tokens=*" %%a in (`git rev-parse --abbrev-ref HEAD`) do @set GIT_BRANCH=%%a

dotnet build -p:Version="1.0.0-alpha.%GIT_COMMIT%"
dotnet pack --no-build -p:PackageVersion="1.0.0-alpha.%GIT_COMMIT%"
"""

これで、製品バージョンに 1.0.0-alpha.xxxxxxx と埋め込まれたDllを含めた、 assemblyInfoTest.1.0.0-alpha.xxxxxxx.nupkg が出来ました。

1.0.0-aplpha のところはまあどこかで一元的に定義しないといけないですけどね。

Karabiner-ElementsでMavVimだけ特定のキーマップを除外する

MacにHHKBを付けているので、Karabiner-Elementsにいつもお世話になってます。

仕事ではMacWindowsを同時に使うのでMacWindowsキーバインドをある程度あわせたくて、Complex Modificationsに PC-Style Shortcuts の中から PC-Style Copy/Paste/Cut を追加しています。

ところでVimで矩形選択をたまにしたくなるのですが「Ctrl + v」がペーストになってしまいます。
iTerm2の中でVim使ってるときはうまくいくのだからこれはなにかの設定に違いない。。。

ぐぐるfrontmost_application_unless を設定しなさいということらしい。

qiita.com

~/.config/karabiner/assets/complex_modifications/ を探ると 1543454397.jsonPC-Style Shortcuts のようです。
※ このファイル名、別のMacで見てみたら違ってました。

「Ctrl + v」を探すと

        {
          "type": "basic",
          "from": {
            "key_code": "v",
            "modifiers": {
              "mandatory": [
                "control"
              ],
              "optional": [
                "any"
              ]
            }
          },
          "to": [
            {
              "key_code": "v",
              "modifiers": [
                "left_command"
              ]
            }
          ],
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "^com\\.microsoft\\.rdc$",
                "^com\\.microsoft\\.rdc\\.mac$",
                "^com\\.microsoft\\.rdc\\.macos$",
                "^com\\.microsoft\\.rdc\\.osx\\.beta$",
                "^net\\.sf\\.cord$",
                "^com\\.thinomenon\\.RemoteDesktopConnection$",
                "^com\\.itap-mobile\\.qmote$",
                "^com\\.nulana\\.remotixmac$",
                "^com\\.p5sys\\.jump\\.mac\\.viewer$",
                "^com\\.p5sys\\.jump\\.mac\\.viewer\\.web$",
                "^com\\.teamviewer\\.TeamViewer$",
                "^com\\.vmware\\.horizon$",
                "^com\\.2X\\.Client\\.Mac$",
                "^com\\.vmware\\.fusion$",
                "^com\\.vmware\\.horizon$",
                "^com\\.vmware\\.view$",
                "^com\\.parallels\\.desktop$",
                "^com\\.parallels\\.vm$",
                "^com\\.parallels\\.desktop\\.console$",
                "^org\\.virtualbox\\.app\\.VirtualBoxVM$",
                "^com\\.vmware\\.proxyApp\\.",
                "^com\\.parallels\\.winapp\\.",
                "^com\\.apple\\.Terminal$",
                "^com\\.googlecode\\.iterm2$",
                "^co\\.zeit\\.hyperterm$",
                "^co\\.zeit\\.hyper$",
                "^io\\.alacritty$",
                "^net\\.kovidgoyal\\.kitty$"
              ]
            }

とありました。やっぱり iterm2 設定されてる。

ここにMacVimを追加しよう! Karabiner-ElementsのEvenViewerを立ち上げて、「Frontmost Application」にしてからMacVimを触ると

Bundle Identifier:  org.vim.MacVim
File Path:          /Applications/MacVim.app/Contents/MacOS/MacVim

と出ます。 ということで↑の bundle_identifiers

                "^org\\.vim\\.MacVim$"

を追加します。

これでKarabiner-Elementsを再起動すればいいと思ったのですがどうも反映しない。
Complex Modificationsで PC-Style Copy/Paste/Cut をremoveしてからadd ruleしてみたら反映した!

f:id:gozuk16:20190830184916p:plain

やっと出来たー。

MacからWindowsファイル共有(日本語で濁点あり)をマウントする

ちょっとターミナルでやりたかったので調べたら今はmountコマンドでやるらしい。

$ mount -t smbfs //username:passwd@hostname/hogehoge ~/mnt/hogehoge

↑これは普通にできる。

で実際に、共有したい所を見てみたら日本語じゃないか。嫌な予感・・・。

$ mount -t smbfs //username:passwd@hostname/ほげほげ ~/mnt/hogehoge
mount_smbfs: URL parsing failed, please correct the URL and try again: Invalid argument

やっぱりね。 _| ̄|○
調べてみたら日本語というより濁点がいけないらしい。

qiita.com

URLエンコードしとけばいいとのことなので、

$ mount -t smbfs //username:passwd@hostname/%E3%81%BB%E3%81%92%E3%81%BB%E3%81%92 ~/mnt/hogehoge

できたー。 (^^)

Google Domains で .dev ドメイン取得

購入

Googleが .dev ドメインを開放していくつかのレジストラで取得できるようになったらしいですが、とりあえず一番安そうな Google Domainsで取ってみました。 初日ほど混んでなくて普通にドメイン検索できました。

まずは、

domains.google

で、hogehoge.dev とかなんとか検索すると値段が出ます。 メジャーじゃない名前やで4文字以上ならだいたい1,400円/年で出てくるようです。 有名な人や企業、地名の名前や辞書に載っているような単語は結構高いものもあるようです。 (ちなみにhogehoge.devはUnavailableでした)

気に入ればカートに入れて購入します。 デフォルトで自動更新になっているようです。(とりあえず自動更新にしておきました)

購入に進むと、名前と住所などを入れるフォームが出てきます。 とりあえず日本語はやめておいて英語っぽく半角英数で入れておきました。

次に進むと、Google Payで支払うかと聞いてきます。 どうやらブラウザでログインしていたGoogleアカウントと自動的に紐づけたようです。 ここでポチッと押すとメールが飛んできて、メールの中の「メールアドレスを確認」を押せば購入完了です。

そういえばドメインを買うときは英語しかなさそうでしたけど、買った後でGoogle Domainsにログインして管理するところは右下の言語設定を日本語にすると切り替わりました。
最初開くと日本語になってるけど、あえて日本語をもう一度選んでから保存すると切り替わりましたw

名前解決

もともとGCEの無料インスタンスで遊んでいたついでに.devドメインの事を思い出したので、名前解決ができるようにします。

固定IP設定

普通にGCEのインスタンスを作成すると外部IPがエフェメラルになってます。
まずは固定IPにしちゃいます。
手順は、

  1. インスタンスを選択
  2. 編集
  3. ネットワーク インターフェース > 外部IP > IPアドレスを作成

です。
これで名前をつければ外向けの固定IPが確保できます。

ネットワークサービス階層
 プレミアム (現在のプロジェクトレベル階層、変更)
 標準

という選択肢があるのですが、無料でやりたいがゆえに標準にしてしまうと割り当てるインスタンスと階層が違うとかなんとか言われてうまくいきません。
とりあえずプレミアムでいいっぽいです。
私は一度消して作り直しました。

f:id:gozuk16:20190306232737p:plain

作成した固定IPが外部IPに出ていればおけ。

f:id:gozuk16:20190306233040p:plain

外部IPを予約して使わないと課金されるのでいらなくなったら消すのを忘れずに。
だいぶ昔の記憶ですがAWSもそんな感じでしたね。

DNS設定

ドメインもIPも準備できたら名前解決しよう。
Google DomainsでもCloud DNSでも出来そうですが、今回はCloud DNSでやりました。(なんとなく)

  1. Cloud DNSドメインの設定 GCPのメニューから、ネットワーキング > ネットワークサービス > Cloud DNSを選択。
    ゾーンの作成からソーン名と自分が取ったドメイン名を入れます。
    DNSSECはデフォルトオフだったのでそのまま。(よく知らないのでちゃんと調べてからでもいいかな)
    これでNSレコードができます。
    f:id:gozuk16:20190306233316p:plain
    4つのDNSサーバが登録されているので控えておきます。
    f:id:gozuk16:20190306233516p:plain
  2. Google Domainsの設定 Google Domainsにログインすると管理画面に入れます。
    ドメインを選ぶと右のメニューにDNSとあるのでここを開いて、ネームサーバーの設定をします。
    デフォルトでGoogleのネームサーバが設定されているのですが↑で作ったNSレコードのサーバと違うので、カスタムネームサーバーを使用するにして登録します。(同じならもちろん何もする必要ないですけど) f:id:gozuk16:20190306233620p:plain
  3. サブドメインの設定 Cloud DNSに戻って、ゾーン > 作ったゾーンを選択 > ゾーンの詳細 > レコードセットを追加 します。
    ドメイン名でAレコード作ります。
    DNS名:example.dev
    リソースレコードのタイプ:A
    IPv4アドレス:先程作った固定IP
    にします。TTLはデフォルトの5分のまま作りましたが、落ち着いたら伸ばしておけばよいかも。
    後はとりあえずwwwだけ登録。
    DNS名:www.example.dev
    リソースレコードのタイプ:CNAME
    正規名:example.dev
    です。
  4. 確認 TTL 5分なので、5分たったら確認です。
    自分のMac
$ dig www.example.dev

;; ANSWER SECTION:
www.example.dev.        300 IN  CNAME   example.dev.
example.dev.        300 IN  A   xx.xx.xx.xx

おー、引けてる!
こりゃ簡単だ〜。
bindのコンパイルからやってた時代にとあるコミュニティのサーバ管理やってたけど隔世の感あるなぁ。
クラウド素晴らしい。

あとは

SSHを別ポートであげるのはやった。
devドメインhttpsじゃないといけないので証明書を設定しなきゃだけど、Google-managed SSL certificateってものがあって中身はLet's Encriptらしい。
ロードバランサー(負荷分散)から登録するということらしいのでまだ試してないが無料の範囲でできるならやってみようかな。それともLet's Encriptを自動更新するようにしたほうがいいか。

まあ、また時間が取れたら考えよ。

Confluenceでバックスラッシュと円マークの表記を使い分ける(Windows限定)

Confluenceでは通常、バックスラッシュ「\」で表示されるがWindowsのパスのように円マーク「¥」で表記したい場合は「等幅フォント」にするとよい。

Windowsでは円マークで見えているが、Macでは等幅フォントのバックスラッシュなのでほとんど区別がつかない。Macで作業する人は要注意

Ubuntu 18.04になって時計合わせがntpdateからsystemd-timesyncdに変わってたので設定した

まずは現状確認。

$ sudo systemctl -l status systemd-timesyncd
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-07-30 21:09:27 JST; 4h 4min ago
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 586 (systemd-timesyn)
   Status: "Idle."
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/systemd-timesyncd.service
           └─586 /lib/systemd/systemd-timesyncd

 7月 30 23:32:11 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.91.157:123 (ntp.ubuntu.com).
 7月 30 23:32:22 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.94.4:123 (ntp.ubuntu.com).
 7月 31 00:06:40 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.91.157:123 (ntp.ubuntu.com).
 7月 31 00:06:50 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.89.199:123 (ntp.ubuntu.com).
 7月 31 00:07:01 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.94.4:123 (ntp.ubuntu.com).
 7月 31 00:07:11 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.89.198:123 (ntp.ubuntu.com).
 7月 31 00:41:29 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.91.157:123 (ntp.ubuntu.com).
 7月 31 00:41:40 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.89.199:123 (ntp.ubuntu.com).
 7月 31 00:41:50 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.94.4:123 (ntp.ubuntu.com).
 7月 31 00:42:00 arianrhod systemd-timesyncd[586]: Timed out waiting for reply from 91.189.89.198:123 (ntp.ubuntu.com).

なんか外へ行こうとしてるな。
ま、設定してないんだから当然か。

それでは社内のNTPサーバを設定します。

$ sudo vi systemd/timesyncd.conf

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See timesyncd.conf(5) for details.

[Time]
NTP=192.168.1.200
#FallbackNTP=ntp.ubuntu.com
#RootDistanceMaxSec=5
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048

$ sudo systemctl restart systemd-timesyncd

確認確認っと。

$ sudo systemctl -l status systemd-timesyncd
● systemd-timesyncd.service - Network Time Synchronization
   Loaded: loaded (/lib/systemd/system/systemd-timesyncd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2018-07-31 01:17:22 JST; 7h left
     Docs: man:systemd-timesyncd.service(8)
 Main PID: 7288 (systemd-timesyn)
   Status: "Synchronized to time server 192.168.1.200:123 (192.168.1.200)."
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/systemd-timesyncd.service
           └─7288 /lib/systemd/systemd-timesyncd

 7月 31 01:17:22 arianrhod systemd[1]: Starting Network Time Synchronization...
 7月 31 01:17:22 arianrhod systemd[1]: Started Network Time Synchronization.
 7月 30 17:17:21 arianrhod systemd-timesyncd[7288]: Synchronized to time server 192.168.1.200:123 (192.168.1.200).

$ date
2018年  7月 30日 月曜日 17:17:33 JST

ちゃんと動きましたー。

VirtualBox上のWindows 10起動時にストレージ絡みのエラーが出る

エラーメッセージは以下通り。

ata2 master: Unknown device
ata2 slave: Unknown device
ata3 master: Unknown device
ata3 slave: Unknown device

VMWare ESXiで調整した仮想マシンをovfでExportしてVirtualBoxでImportしたらエラーが出た。
ぐぐる

ask.sagemath.org

というページにあたったたので、設定 > ストレージ > コントローラー:SATA > ポートの数 を確認したら30になってた。
これを4に変えたらエラー消えました。

最初に一通り設定見たときに、30ってなんか変だなぁと思ったけどまさかこれが関係するとは思ってなかったのでスルーしてた。

ちなみに、Import直後はなぜかvmdkが所属するコントローラーがSASになってたので、SATAに付け替えたけどちゃんと動いています。