Jaybanuan's Blog

どうせまた調べるハメになることをメモしていくブログ

pyyamlでのYAMLの読み込みと書き込み

はじめに

PythonYAMLパーサのpyyamlを利用して、YAMLのデシリアライズシリアライズするコードスニペットと、その説明をメモしておく。

コード例

import yaml

with open('input.yml') as file:
    data = yaml.load(file, Loader=yaml.CLoader)

with open('output.yml', 'w') as file:
    yaml.dump(data, file, allow_unicode=True, default_flow_style=False, sort_keys=False)

load()によるデシリアライズ

load()の呼び出しにはLoaderの指定が必要。 指定しなくても実行できるが、以下のような警告文が出力される。

test.py:30: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  data = yaml.load(file)

過去はLoaderの指定は不要だったようだが、インタフェースを保ちつつ脆弱性への対応を行うためにこうなったらしい。 詳細は以下を参照。

dump()によるシリアライズ

dump()で実用的なYAMLを書き出す際には、いくつかのフラグをつけておいたほうが視認性が良くなる。

  • allow_unicode

    • UNICODE文字を許すかどうか。Falseの場合は\uエンコードされた文字列が出力される。
  • default_flow_style

    • YAMLをフロースタイルで出力すると、横に長く伸びるので、視認性が悪くなる。
  • sort_keys

    • キーをソートしてその順番で出力するかどうか。登録順で出力しなたいならFalseを指定しておく。YAMLの内容がデータなら出力順序が重要ではない場合もあるが、YAML形式の設定ファイル等の場合は元の順序を保っていたほうが分かりやすい。

YAMLのJSON Schema

YAML 1.2の仕様に「JSON Schema」なるものがあるが、今までこれが何者なのかよく分からなかった。

しかし、以下の2つの記事のおかげで、YAMLのJSON SchemaYAMLのデータ型をJSONのデータ型と合わせるための制約であり、JSONのJSON Schemaとは名前が同じだが全く別物だということが、ようやく理解できた。

名前の付け方って大事だと改めて思った。

www.educative.io

blogs.perl.org

dpkgのよく使う実行方法

はじめに

dpkgのよく使う実行方法をまとめておく。

指定したファイルが含まれるパッケージを調べる

以下は/bin/psがどのパッケージに含まれているかを調べる例。 procpsというパッケージに含まれていることが分かる。

$ dpkg -S /bin/ps
procps: /bin/ps

パッケージに含まれるファイルの一覧を表示する

以下はパッケージ/procpsに含まれるファイルの一覧を表示する例。

$ dpkg -L procps
/.
/bin
/bin/kill
/bin/ps
/etc
/etc/init.d
/etc/init.d/procps
/etc/sysctl.conf
(以下略)

コンテナイメージの名前について調べたメモ

はじめに

コンテナイメージの名前について、厳密の考えると色々ややこしいので、調べてまとめてみようと思った。 しかし、泥臭い変換や補完があったりして、キレイにはまとまらず。 ただ、せっかく調べたのでメモは残しておく。

環境

Docker CLIを前提として、主に最新のドキュメントとソースコードを中心に情報を収集した。 Podman等の別のコンテナ実装や、KubernetesのようなPaaS上でコンテナを扱うときは、異なる仕様/挙動になるかもしれない。 コマンドラインでの試行や設定ファイルの確認は、以下の環境で実施している。

$ cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Ubuntu 20.04.3 LTS"

$ docker --version
Docker version 20.10.8, build 3967b7d

コンテナイメージの名前の構成要素

「コンテナイメージの名前」と書いてみたものの、正しい表現かどうかはよく分からない。 「イメージ名(image name)」と呼ばれることが多い気がするが、文脈によっては誤解しそうなので、ここではあえて「コンテナイメージの名前」と表記しておくことにする。 また、Docker CLIソースコードの中では「リファレンス(reference)」と呼ばれているようだ。

コンテナイメージの名前のフォーマットは、ざっくりとは以下のような感じ。

hostname:1234/path/name:1.0.0
\___________/ \_______/ \___/
   ドメイン       パス     タグ
\_____________________/
        リポジトリ

ドメインは省略可能で、省略した場合はDocker CLIだとregistry-1.docker.ioになるようだ。 個人的な感覚としては、「ドメイン」というよりは、Container Registryの「APIサーバ」という表現の方が、名が体を表しているように思う。

以下に、リポジトリとタグの例として、docker image lsの結果を挙げておく。 表示された表の1行目がリポジトリ、2行目がタグであることが分かる。

$ docker image ls
REPOSITORY              TAG       IMAGE ID       CREATED        SIZE
hello-world             latest    d1165f221234   6 months ago   13.3kB
quay.io/centos/centos   latest    300e315adb2f   9 months ago   209MB

なお、コンテナイメージの名前の正確なフォーマット(文法)は、ソースコード中のコメントより、以下の通り。 この文法の中では「リファレンス」と呼ばれている。

// Grammar
//
//  reference                       := name [ ":" tag ] [ "@" digest ]
//  name                            := [domain '/'] path-component ['/' path-component]*
//  domain                          := domain-component ['.' domain-component]* [':' port-number]
//  domain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/
//  port-number                     := /[0-9]+/
//  path-component                  := alpha-numeric [separator alpha-numeric]*
//  alpha-numeric                   := /[a-z0-9]+/
//  separator                       := /[_.]|__|[-]*/
//
//  tag                             := /[\w][\w.-]{0,127}/
//
//  digest                          := digest-algorithm ":" digest-hex
//  digest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*
//  digest-algorithm-separator      := /[+.-_]/
//  digest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/
//  digest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value
//
//  identifier                      := /[a-f0-9]{64}/
//  short-identifier                := /[a-f0-9]{6,64}/

少々気になるのが、文法的にdomainpath-componentの区別に曖昧さがあり、このままだと「path-componentのつもりで書いたのにdomainと解釈された」ということが起こりそうだということ。 推測だが、どこかで「パーサがdomainと解釈したけど、本当にドメイン(=APIサーバ)なの?」という追加の検査をしていそうに思える。

ドメインの省略について

先ほど「省略した場合はDocker CLIだとregistry-1.docker.ioになるようだ」と書いたが、これはドキュメントから引っ張ってきた情報である。 しかし実際には、ドメインを省略した場合の、ドメインの決定方法は設定によって変更できるようだ。 例えば、調査した環境では、/etc/containers/registries.confというファイルに、省略したドメインを補完するための設定情報がある。

(略)
# # An array of host[:port] registries to try when pulling an unqualified image, in order.
unqualified-search-registries = ["docker.io", "quay.io"]
(略)

また、コンテナイメージの名前にエイリアスをつけることができるようであり、これを利用して補完(というかマッピング)することもできる。 調査した環境では、エイリアス/etc/containers/registries.conf.d/000-shortnames.confで定義されていたので、その一部を以下に示しておく。

[aliases]
  # centos
  "centos" = "quay.io/centos/centos"
  # containers
  "skopeo" = "quay.io/skopeo/stable"
  "buildah" = "quay.io/buildah/stable"
  "podman" = "quay.io/podman/stable"
  # docker
  "alpine" = "docker.io/library/alpine"
  "docker" = "docker.io/library/docker"
  "registry" = "docker.io/library/registry"
  "hello-world" = "docker.io/library/hello-world"
  "swarm" = "docker.io/library/swarm"
  # Fedora
  "fedora-minimal" = "registry.fedoraproject.org/fedora-minimal"
  "fedora" = "registry.fedoraproject.org/fedora"
(以下略)

特別なパスlibrary/

DockerHub公認のコンテナイメージは特別扱いされており、パスがlibrary/で始まる。 例えば、上記のエイリアスの中にも含まれているが、docker.io/library/hello-world等がそれにあたる。 具体的な処理内容までは追いきれていないが、ソースコード中に、パスのプレフィックスlibrary/かどうかで条件分岐している処理が数カ所確認できた。

参考

Windows Updateができない場合の対処

Windows Updateがエラーコード0x80244019で失敗する。 Windows Update中にマシンがダウンしたような形跡もあるので、以下の記事を参考にWindows Updateの残骸を消したところ、問題が解消した。

forest.watch.impress.co.jp

コマンドプロンプトから以下を実行した。

net stop usosvc
net stop dosvc
net stop wuauserv
net stop bits
move %SystemRoot%\SoftwareDistribution %SystemRoot%\SoftwareDistribution.old
del %ALLUSERSPROFILE%\Microsoft\Network\Downloader\qmgr0.dat
del %ALLUSERSPROFILE%\Microsoft\Network\Downloader\qmgr1.dat
net start bits
net start wuauserv
net start dosvc
net start usosvc
%SystemRoot%\system32\usoclient.exe StartScan

Windowsのバージョンによっても微妙に手順が違う可能性があるので、実施する場合は最新情報(特にMSのサイト)がないかはチェックする必要がある。

参考