20200919のLinuxに関する記事は7件です。

vimのカラースキームを変更する方法

Linuxなどのコンソールでファイルをvimで開いたときに色が見にくい時があります。

そんな時に色を変更する方法をメモがてら共有します。

vimを開いてから変更する方法

①コロン(:)をうちコマンドモードにし「colorscheme」と入力します。colorと入力してtabキーを入力すれば保管されます。
②tabキーを押して使用したいカラースキームを選択します。
例えば「elflord」というカラースキームを変更する際には以下のようになります。

:colorscheme elflord

恒常的にカラースキームを設定する方法

vimを開くたびにカラースキーム設定をするのは面倒です。

そこでデフォルトのカラースキームを設定します。
設定を書き込むのは「vimrc」というファイルです。

vimrcは各ユーザーのホームディレクトリ配下に隠しファイルとして用意されています。

なので以下のように開けます。

vim ~/.vimrc

そして以下のように書き込み保存します。(カラースキームとしてelfordを使用した場合)

colorscheme elflord

vimrcはvimを開いたときに設定として読み込まれますのであとはvimを開けばカラースキームは自動で置き換わってくれます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Electronアプリをビルド・発行する時のプラットフォームにおける制約とネイティブモジュールとの関係

Electronを用いるとクロスプラットフォームな開発ができることは皆さんご存じの通りです。

しかし、ビルド→発行としていくなかで、それらの作業がすべて一つのプラットフォーム上で完結するというわけではありません

また、ネイティブモジュールを利用する場合は、話が異なります

そこらへんについて説明していこうと思います。

一つのプラットフォームですべてのプラットフォームにたいしてビルド・発行できるか

例えば「WindowsですべてのOS向けのアプリをビルドできるか?」という問題ですが、ネイティブモジュールの利用有無次第となります。

ネイティブモジュールを利用していない場合

ビルドはできます

ただし、Mac向けの発行はCode Signingが必要になるため、Mac上でしかできません

よって、Mac上で動かせば、ビルドから発行まですべてMac上で完結します。

Docker イメージ

electron-builderを動かせる環境として、Dockerイメージが用意されています。

しかし、これはLinux上で動かすのと同じなので、WindowsとLinux向けのアプリのビルド・発行しかできません。

また、Windows用のネイティブモジュールを利用する場合は、ビルドもできません。

ネイティブモジュールについては、次の節で説明します。

ネイティブモジュールを利用している場合

ネイティブモジュールは各OS向けにそれぞれビルドする必要があります。

よって、基本的にはターゲットとなるプラットフォームの数だけビルド環境を用意する必要があります。

Macのネイティブモジュールをビルドするなら、Mac。

WindowsならWindowsのビルド環境が必要です。

昨今は、Mac用のVMも用意されていることを考えると、用意することは難しいことではないかもしれませんが、開発に当たっては実機が必要になることに間違いはないでしょう。

ネイティブモジュールを使わずとも、多くの機能が実装できることは確かですが、いつかはぶち当たる問題になります。

必要になったらで良いとは思いますが、ネイティブモジュールとそれに伴うビルド・発行環境の用意を検討する必要があるでしょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WindowsでLinuxの仮想マシンを作成

1.目的

作成中

2.参考サイト

https://eng-entrance.com/linux-centos-install

3.必要なもの

作成中

4.ぶつかった問題

作成中

5.解決策

作成中

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git基本事項

用語(編集途中)

コミット

ユーザーが任意のタイミングで記録を保存する操作.

リポジトリ

コミットを貯めておく場所.

すでにGitで管理されているプロジェクトの開発に参加する場合はリポジトリをコピー(クローン)して使う.

ワークツリー

変更するファイルを保持する場所.

ステージングエリア

コミットするファイルを登録する場所.

Gitディレクトリ

コミットを格納する場所.

GitHubにあげるまでの手順

今回はGitのインストールやGitHubのアカウント作成などの初期設定の説明は省く.

あらかじめ登録してある人が新しいプロジェクトを始めるという状況を想定.

リモートリポジトリをローカルへ複製する or ローカルで作成したリポジトリをリモートへ反映させる

今回はリモート側のリポジトリとして先にGitHubへリポジトリを作成し,それをローカルへ複製するという方法で進める.

    $ git clone GitHubのリポジトリURL

GitHubのファイルが複製されるので cd コマンドでコピーしたディレクトリに移動する.

作業用ブランチを作成する

Gitではbranchを作成し作業を行い,完成したらmasterにmergeするのが基本なのでここでbranchを作成する.

以下のコマンドで現在いるbranchが確認できる.

    $ git branch
    * master

ブランチの作成には以下のコマンドを使う.

    $ git branch ブランチ名

例)

    $ git branch work

ブランチを作成したら以下のコマンドでブランチを切り替える

    $ git checkout ブランチ名

例)

    $ git checkout work

ブランチを切り替えたらファイルの編集を行い,バージョンアップを行う.

コミットをする

書き換えたファイルはリモートリポジトリに保存しておきたいので以下のコマンドを実行する.
    $ git add ファイル名

このコマンドで指定したファイルがコミット対象になる.

今回はフォルダにあるファイルを全てコミットする予定なので以下のコマンドを実行する.

    $ git add .

これでコミットの準備ができたので以下のコマンドでコミットを行う.

    $ git commit -m 'コメント’

これでコミットは完了.(-mを付けなかった場合はvi上でコメントの入力を求められる.)

ブランチをマージする

今回はmasterにworkを取り込む.

まずはmasterブランチに移動する.
    $ git checkout master
    Switched to branch 'master'
    Your branch is up to date with 'origin/master'.

このまま編集したファイルを開いてもブランチを切り替えているので変更が反映されていない.

例)

    $ git merge work
    Updating ac63b89..3eefb35
    Fast-forward
    README.md | 1 +
    1 file changed, 1 insertion(+)

このコマンドでマージが成功すると編集した内容がmasterに反映される.

リモートにpushをする

いよいよ変更内容をGItHubに反映させる.

例)

    $ git push origin work
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (2/2), done.
    Writing objects: 100% (3/3), 338 bytes | 338.00 KiB/s, done.
    Total 3 (delta 1), reused 0 (delta 0)
    remote: Resolving deltas: 100% (1/1), completed with 1 local object.
    remote: 
    remote: Create a pull request for 'work' on GitHub by visiting:
    remote:      GitHubのURL
    remote: 
    To GitHubのURL
    * [new branch]      work -> work

これでGitHubにちゃんと反映されていたら成功!

おさらい

大事なのは以下のコマンドでこの流れは絶対である.
    $ git clone URL
    $ git add .
    $ git commit -m 'コメント'
    $ git push origin master

知っていると便利なコマンド

    $ git status

このコマンドで今の状態を確認できる.

慣れるまでは何かを実行するたびにこのコマンドで確認した方がいいかも.

    $ git branch

このコマンドで現在どのブランチにいるのかを確認できる.

不十分な点

  • 開発はGitHub→Gitという流れよりローカル→リモートという流れが自然?
  • ブランチ切ったままファイルの移動をしてしまった場合どうなっちゃう?
  • 後からフォルダに違うディレクトリ にあったファイルを持ってきた場合どうやったらコミット対象になってくれるのか
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Bash】安全で汎用性のあるtempディレクトリの作成

はじめに

  • 普段shell内で利用する一時ディレクトリ作成において、以下の点で改善点が見受けられた。
    • mkdir /tmp/パスのような直指定のため、場合によって名前の重複が生じる。
    • また直指定のため、セキュリティ的に安全ではない。
    • 名前を一意にして関連性も加えることで、処理内で使いやすく汎用性のあるものにする必要がある。
  • そのため、今回は一意で安全かつ汎用性のあるtmpディレクトリの作成方法を記述する。

結果

  • 先に結果として下記の内容を、用意したシェルファイルに記述する。
index.sh
#!/bin/bash

basepath=$(basename $0)
timestamp=$(date +%Y%m%d%H%M%S)
tmpd=$(mktemp -dt "$basepath.$timestamp.$$")/
echo $tmpd

# 出力
# $TMPDIR/index.sh.20200919152709.XXXX.XXXXX/
  • 記述後、複数回実行して出力したパスへの作成や名前の非重複を確認して、完了。

処理内容

mktempコマンドの利用

  • ディレクトリ作成にmktempコマンドを利用することで、自動でサイズ0のファイルやディレクトリを作成してくれる。
    • mktempの詳細な利用方法はこちらを参考

テンプレートオプションの利用

  • mktempでの作成の際に、このコマンド固有のオプションのt(テンプレート)オプションを利用する。
  • そうすることにより、ディレクトリ名を記述しなくても自動で$TMPDIRに設定されたパス内へ作成してくれる。
    • ※設定されているtmp格納場所を探す際は、echo $TMPDIRで探す
    • ※設定されていない場合、-pで直指定を行うか、/tmpに格納される

名前に関連項目も加える

  • 名前に関連性のあるものを加えておき、プログラムでの処理の際に利用しやすくする。
  • 最低限加えているものは下記。
    • 実行パス名
    • タイムスタンプ(時間)

まとめ

  • 上記のことから、Linuxでは課題を解決するための多数のコマンドが標準で備わっているため、これらを1つでも覚えて組み合わせていくことの重要性を再確認。
  • また、安全面の考慮も必要だが、同時にプログラム内での処理の使いやすさや汎用性への意識の重要性を実感。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Linux デスクトップKDE+Nvidiaでサスペンド後にChromeとかがおかしくなる問題

症状

今回説明するものは次の2つです。

  • サスペンド後にChromeの描画が崩れる問題 ← Chrome再起動で症状は治まる
  • サスペンド後にsystemsettings5 の描画が崩れる問題 ← systemsettings5は再起動しても治らない

image.png
↑ Chromeの描画が崩れる問題

image.png
↑systemsettings5 (崩れている画面のスクショはないですがこんなやつ)

環境 (関係しそうなもののみ)

  • OS: Arch Linux (これは恐らく関係なくて、Ubuntuとかでも一緒と思われます)
  • GPU: Nvidia RTX GeForce 2070 Mobile
  • GPU Driver: 450系
  • デスクトップ: KDE Plasma 5.19系

TL;DR

次の2つの方法を両方実行すれば治りました(再発したら記事更新します)。

  • systemsettings5: Nvidia Driverを450系から440系にダウングレード
  • Chrome: GUIの「設定→詳細設定→ハードウェアアクセラレータを有効化」を無効にする

調査記録

事前の準備と警告

グラフィックドライバの問題が絡むので、調査や自身の環境への適用の際に試行錯誤している中でカーネルパニックを起こしてブートできない場合があります
作業前にはインストーラとかでchrootできる環境を整えておきましょう

systemsettings5の方

こちらは次のコマンドで起動できるので調査は容易です。

  • 正常なときにsystemsettings5 &> logOk
  • おかしいときにsystemsettings5 &> logNg
logOk
Cyclic dependency detected between "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml" and "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml"
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/SubCategoryPage.qml:141:9: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/SubCategoryPage.qml:131:9: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/lib/qt/qml/org/kde/kirigami.2/private/RefreshableScrollView.qml:143:13: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/lib/qt/qml/org/kde/kirigami.2/private/RefreshableScrollView.qml:143:13: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
Cyclic dependency detected between "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml" and "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml"
QQmlEngine::setContextForObject(): Object already has a QQmlContext
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/introPage.qml:109:27: QML IntroIcon (parent or ancestor of QQuickLayoutAttached): Binding loop detected for property "minimumHeight"
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/introPage.qml:109:27: QML IntroIcon (parent or ancestor of QQuickLayoutAttached): Binding loop detected for property "minimumHeight"
logNg
Cyclic dependency detected between "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml" and "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml"
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/SubCategoryPage.qml:141:9: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/SubCategoryPage.qml:131:9: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/lib/qt/qml/org/kde/kirigami.2/private/RefreshableScrollView.qml:143:13: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
file:///usr/lib/qt/qml/org/kde/kirigami.2/private/RefreshableScrollView.qml:143:13: QML Connections: Implicitly defined onFoo properties in Connections are deprecated. Use this syntax instead: function onFoo(<arguments>) { ... }
Cyclic dependency detected between "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml" and "file:///usr/lib/qt/qml/org/kde/kirigami.2/styles/org.kde.desktop.plasma/Units.qml"
QQmlEngine::setContextForObject(): Object already has a QQmlContext
+ QQuickWidget: Failed to make context current
+ QQuickWidget::resizeEvent() no OpenGL context
+ QQuickWidget: Failed to make context current
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/introPage.qml:109:27: QML IntroIcon (parent or ancestor of QQuickLayoutAttached): Binding loop detected for property "minimumHeight"
file:///usr/share/kpackage/genericqml/org.kde.systemsettings.sidebar/contents/ui/introPage.qml:109:27: QML IntroIcon (parent or ancestor of QQuickLayoutAttached): Binding loop detected for property "minimumHeight"
+ QQuickWidget: Attempted to render scene with no context
+ QQuickWidget::invalidateRenderControl could not make context current

エラーメッセージが特定できればググるだけですね。
https://bbs.archlinux.org/viewtopic.php?id=258149
こういうフォーラムがヒットして「ダウングレードしたら行けたよ!」
とのことです。関連スレッドを見ると、Nvidia450系とKDE Plasma 5.19系の問題のようですね。
ちな、nvidiaのドライバはカーネルに深く関わっているのでnvidia-dkms的な方をインストールする必要がありそうです。

LinuxにおけるダウングレードはそれぞれのOSで作法があると思うので、手元の環境で行った記録を書いておきます archのref

archLinuxの場合
yay -S nvidia-dkms downgrader # nvidia-dkms と nvidia-utils がインストールされる
yay -R nvidia-dkms
downgrader nvidia-utils # 選択肢でバージョン`440.100-1`を選ぶ
yay -S nvidia-440xx-dkms
sudo reboot

chromeの方

こちらは明確なエラーメッセージを探すことができなかったのでちょっと困りました。
最も確実な解決法は GUIの「設定→詳細設定→ハードウェアアクセラレータを有効化」を無効にすることです。
これを行うとChromeはGPU資源を使わなくなるので問題は解決しますが、描画が遅くなり、CPUリソースをより消費します。

他にも
* chrome://flags
* #ignore-gpu-blacklistまたは#ignore-gpu-blocklistを有効化
* #enable-vulkanを有効化

2020-09-19 追記
Chromeの描画が崩れる問題は別の問題が発生したため解決していません。
enable-vulkanを有効化すると時折kwinを巻き込んでクラッシュします。

組合せ

systemsettings5 chrome
nvidia-450 NG restartで治る
nvidia-vulkan-450 NG crashが続く
nvidia-440xx-dkms OK restartで治る
nvidia-vulkan-dkms-450 NG crashが続く

Chomeは以下どちらの場合でも時折kwinを巻き込んでクラッシュします(3回に1度程度ログインセッションも巻き込んでクラッシュ)。

  • ドライバにvulkan系のものを使う
  • enable-vulkanを有効化する

ログインセッションがクラッシュした場合でも該当のセッション内で起動していたプロセスは生きていました(!)。他のttyからも確認できず、psで生存が確認できてかつ正常に動作することが確認できる状態でした。これらを消すのはkillするしかないのでは。。

ログインセッションを巻き込まない場合のログ(一部)
# journalctl -b -p3
Sep 19 10:19:52 archlinux systemd-coredump[13418]: Process 12306 (chrome) of user 1000 dumped core.
                                                   Stack trace of thread 12306:
                                                   #0  0x00007f95b5915c7b n/a (libnvidia-glcore.so.440.100 + 0xee4c7b)
                                                   #1  0x00007f95b59184bd n/a (libnvidia-glcore.so.440.100 + 0xee74bd)
                                                   #2  0x00007f95b5918bfe n/a (libnvidia-glcore.so.440.100 + 0xee7bfe)
                                                   #3  0x00007f95b58b56da n/a (libnvidia-glcore.so.440.100 + 0xe846da)
                                                   #4  0x00007f95b586ac9e n/a (libnvidia-glcore.so.440.100 + 0xe39c9e)
                                                   #5  0x00007f95b5873fdf n/a (libnvidia-glcore.so.440.100 + 0xe42fdf)
                                                   #6  0x00007f95b54d4178 n/a (libnvidia-glcore.so.440.100 + 0xaa3178)
                                                   #7  0x00007f95b54d9068 n/a (libnvidia-glcore.so.440.100 + 0xaa8068)
                                                   #8  0x00007f95b54db97c n/a (libnvidia-glcore.so.440.100 + 0xaaa97c)
                                                   #9  0x00007f95b727cf81 n/a (libGLESv2.so + 0x410f81)
                                                   #10 0x00007f95b726f5a9 n/a (libGLESv2.so + 0x4035a9)
                                                   #11 0x00007f95b713f682 n/a (libGLESv2.so + 0x2d3682)
                                                   #12 0x00007f95b70af266 _ZN2gl22CheckFramebufferStatusEj (libGLESv2.so + 0x243266)
                                                   #13 0x00005567c65a8dad n/a (chrome + 0x633bdad)
(以降略)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NTPサーバ名をDHCPで取得して設定する方法

動機

孤立したローカルネットワーク内にある複数のホスト(Linux)の時刻合わせのため、そのうちの1台でNTPサーバを動かし、他をNTPクライアントで時刻同期をとることとした。各クライアントホストでは、DHCPで配信されたNTPサーバアドレスを設定することにした。

クライアントの設定の方が難儀だった。

NTPサーバの設定、およびDHCPサーバでNTPサーバ情報を配信する設定に関しては、色々な所に書かれている。一方でクライアントの設定に関しては環境依存が大きく適切な情報を見つけるのに時間を要した。クライアント側(Linux)が起動時に行なっている処理は、概ね下記のような手順をとっているようだ。

  1. DHCPクライアントが終了時にスクリプト(hook)を起動する。
  2. DHCPクライアントが起動したスクリプトがNTPクライアントの設定ファイルを更新する。
  3. 更新された設定ファイルを読んで、NTPクライアントが起動される。

ここで環境依存が発生するのは、DHCPクライアント(dhclient(ISC-DHCP), dhcpcd, NetworkManagerのinternal dhcp client, ...)と、NTPクライアント(ntpd, openntpd, chrony, systemd-timesyncd, ...)の組み合わせが多いことによる。Linuxディストリビューションによってはバージョンアップの際にデフォルトとして採用するDHCP,NTPパッケージを変わることがあるようで、それに気づかないとハマる。デフォルトでない(=使用されない)DHCPクライアントやNTPクライアントのパッケージもインストールされていたりすると、使用されることのない設定ファイルを書き換えて所期した動作をせず悩むということがおきる。

Raspberry Pi OS の場合

Raspberry Pi OS (64bit, Debian buster based)では、デフォルトのDHCPクライアント=dhcpcd, NTPクライアント=systemd-timesyncdとなっている。DHCPで呼ばれるhookは、/lib/dhcpcd/dhcpcd-hooks/50-ntp.confのようである。このファイルには、ntpd,openntpd,chrony用の記述はあるがsystemd-timesyncd用の記述がない。公式サイトのフォーラムの情報を元に、下記を追記したところ、システム起動時にNTPサーバが動的に設定されて時刻合わせがされるようになった。/etc/dhcp/dhclient-exit-hooks.d/timesyncdというファイルが存在してそれらしい実装が含まれているが、こちらは使われていないので注意が必要である。

/tmp/dhcpcd_ntp_conf(修正部分;diff出力)
--- /etc/dhcpcd.conf.orig   2019-11-13 23:44:50.000000000 +0900
+++ /etc/dhcpcd.conf    2020-09-16 08:28:53.595999273 +0900
@@ -30,7 +30,7 @@ option classless_static_routes
 option interface_mtu

 # Most distributions have NTP support.
-#option ntp_servers
+option ntp_servers

 # A ServerID is required by RFC2131.
 require dhcp_server_identifier
/lib/dhcpcd/dhcpcd-hooks/50-ntp.conf(追記)
# Set NTP servers for systemd-timesyncd

confd=/run/systemd/timesyncd.conf.d

if [ -n "$new_ntp_servers" ] ; then
    set_servers() {
        mkdir -p "$confd"
        ( echo "# Created by dhcpcd hook";echo "[Time]"; echo "NTP=$new_ntp_servers" ) > "$confd/dhcp-ntp.conf"
        # Tell timesyncd it has an updated configuration
        systemctl try-reload-or-restart systemd-timesyncd
    }
    if $if_up; then
        set_servers
    fi
fi

ちなみに、systemd-timesyncdのデフォルトの設定ファイル(/lib/systemd/system/systemd-timesyncd.service.d/disable-with-time-daemon.conf)では、他のNTPクライアントやVirtualBoxのサービスの実行ファイルが存在していたら何もしないようになっているので、50-ntp.confは置き換えでなく追記にしておいた方が無難とおもわれる。

Ubuntu MATE 20.04 LTS の場合

Raspberry Pi用のイメージ(ubuntu-mate-20.04.1-beta2-desktop-arm64+raspi.img)の場合、使われているのはNetworkManagerのinternal dhcp clientと、systemd-timesyncdの組み合わせのようである。デフォルトでdhclientもインストールされており、/etc/dhcp/dhclient-exit-hooks.d/timesyncdも用意されているので、コマンドラインで手動でdhclientを実行すると時刻の同期がされる。そこで、/etc/NetworkManager/NetworkManager.conf[main]セクションにdhcp=dhclientと追記してinternal dhcpの代わりにdhclientが使われるようにすれば良いかと思いきや、ログを見るとdhclientがエラーを吐いており、また思ったタイミングでhookが呼ばれない。

しかたがないのでdhclientを使うのは諦め、/etc/dhcp/dhclient-exit-hooks.d/timesyncdを参考にNetworkManagerのDispatherスクリプトを用意することにした。公式マニュアルにしたがって環境変数や判定文字列を修正して、/etc/NetworkManager/dispatcher.d/90-dhcp-timesyncdを作成する。

/etc/NetworkManager/dispatcher.d/90-dhcp-timesyncd
#!/bin/sh

TIMESYNCD_CONF=/run/systemd/timesyncd.conf.d/01-dhclient.conf

timesyncd_servers_setup_remove() {
    if [ -e $TIMESYNCD_CONF ]; then
        rm -f $TIMESYNCD_CONF
        systemctl try-restart systemd-timesyncd.service || true
    fi
}

timesyncd_servers_setup_add() {
    if [ ! -d /run/systemd/system ]; then
        return
    fi

    old_ntp_servers=$(sed -ne 's/^NTP=//gp')
    if [ -e $TIMESYNCD_CONF ] && [ "x$DHCP4_NTP_SERVERS" = "x$old_ntp_servers" ]; then
        return
    fi

    if [ -z "${DHCP4_NTP_SERVERS}" ]; then
        timesyncd_servers_setup_remove
        return
    fi

    mkdir -p $(dirname ${TIMESYNCD_CONF})
    cat <<EOF > ${TIMESYNCD_CONF}.new
# NTP server entries received from DHCP server
[Time]
NTP=$DHCP4_NTP_SERVERS
EOF
    mv ${TIMESYNCD_CONF}.new ${TIMESYNCD_CONF}
    systemctl try-restart systemd-timesyncd.service || true
}

logger -i -t "$0"  "action=${NM_DISPATCHER_ACTION}:NTP=${DHCP4_NTP_SERVERS}"

case $NM_DISPATCHER_ACTION in
    up|dhcp4-change)
        timesyncd_servers_setup_add
        ;;
    down)
        timesyncd_servers_setup_remove
        ;;
    *)  :
        ;;
esac

このファイルは、オーナーをrootにして実行パーミッションを与えておく必要がある。

% ls -l /etc/NetworkManager/dispatcher.d/90-dhcp-timesyncd
-rwxr-xr-x 1 root root 1140 Apr  2 02:55 /etc/NetworkManager/dispatcher.d/90-dhcp-timesyncd

このスクリプトを置くことで、時刻の同期がされるようになった。

JetPack 4.4 (Ubuntu 18.04 LTS based)の場合

Ubuntuの一つ前のバージョンでも使われているのはNetworkManagerと、systemd-timesyncdの組み合わせのようである。そのため、前節(Ubuntu MATE 20.04 LTS)と同じスクリプトで動くと思いきや、そのままでは期待した通りに動作してくれなかった。networkmanager-dispatcherのバージョンの違いのせいか、環境変数$NM_DISPATCHER_ACTIONがセットされないようである。そのため、かわりに実行時の第2引数を評価するように下記のように修正することで期待した動作がされるようになった。

NetworkManager-dispatcherのバージョン違いに対応
--- Ubuntu_MATE-20.04LTS/etc/NetworkManager/dispatcher.d/90-dhcp-timesyncd  2020-09-20 21:52:17.950941231 +0900
+++ JetPack-4.4/etc/NetworkManager/dispatcher.d/90-dhcp-timesyncd   2020-09-22 01:18:46.160691469 +0900
@@ -34,9 +34,9 @@ EOF
     systemctl try-restart systemd-timesyncd.service || true
 }

-logger -i -t "$0"  "action=${NM_DISPATCHER_ACTION}:NTP=${DHCP4_NTP_SERVERS}"
+logger -i -t "$0"  "action=${NM_DISPATCHER_ACTION:-${2}}:NTP=${DHCP4_NTP_SERVERS} $@"

-case $NM_DISPATCHER_ACTION in
+case ${NM_DISPATCHER_ACTION:-$2} in
     up|dhcp4-change)
         timesyncd_servers_setup_add
         ;;

余談だが、Ubuntu 18.04 LTSのNetworkManagerは、internal dhcp clientではなく、dhclientを利用しているようだ。

Ubuntu Server 20.04 LTSの場合

systemd-networkdのinternal dhcp clinetとsystemd-timesyncdの組み合わせとなっている模様。とくに何もしなくてもDHCPのNTPサーバが設定されるようになっている。systemd-networkd-dispatcherに関してはあまり情報を見つけられなかったので、どのような仕組みでDHCPで取得されたアドレスがsystemd-timesyncdに渡されているのかは未解明。

CentOS 7.8 (20.03), CentOS 8.2 (20.04)の場合

NetworkManagerchronyの組み合わせになっていて、何もしなくてもDHCPのNTPサーバが設定されるようになっている。余談だが、CentOS 7では、dhclientが使われていて、CentOS 8ではNetworkManagerのinternal dhcp clientが使われているようだある

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む