このステップバイステップガイドでは、/etc/fstab
ファイルの構造を反映するJSON Schemaを設計する方法を学びます。
このガイドは以下のセクションに分かれています。
はじめに
fstabファイルへの制約はすべて、JSON Schema単独ではモデル化できません。ただし、その多くを表すことができ、制約がどのように機能するかを示すのに役立ちます。提供されている例は、fstabファイルの実際の、動作するスキーマではなく、JSON Schemaの概念を示すものです。
この例は、/etc/fstab
ファイルに表示されるファイルシステムのマウントポイントのJSON Schema表現の可能性を示しています。
fstabファイルのエントリにはさまざまな形式があります。以下に例を示します。
{ "/": { "storage": { "type": "disk", "device": "/dev/sda1" }, "fstype": "btrfs", "readonly": true }, "/var": { "storage": { "type": "disk", "label": "8f3ba6f4-5c70-46ec-83af-0d5434953e5f" }, "fstype": "ext4", "options": [ "nosuid" ] }, "/tmp": { "storage": { "type": "tmpfs", "sizeInMB": 64 } }, "/var/www": { "storage": { "type": "nfs", "server": "my.nfs.server", "remotePath": "/exports/mypath" } }}
fstab
スキーマの作成
まず、次の制約を表現するベースJSON Schemaから始めます。
- エントリのリストはJSONオブジェクトである。
- このオブジェクトのメンバー名(またはプロパティ名)はすべて、有効な絶対パスでなければならない。
- ルートファイルシステム(つまり、
/
)のエントリが必要である。
JSON Schemaを上から下に構築する
正規表現が明示的にアンカーされていることに気づくでしょう(^
と $
を使用)。JSON Schema では、(patternProperties
および pattern
の)正規表現はデフォルトではアンカーされていません。

スキーマ
{ "$id": "https://example.com/fstab", "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "type": "object", "required": [ "/" ], "properties": { "/": {} }, "patternProperties": { "^(/[^/]+)+$": {} }, "additionalProperties": false}
entry
スキーマの開始
すでに説明した内容に新しい概念を追加するJSONスキーマのアウトラインから始めます。
前の演習では、$id
、$schema
、type
、required
、およびproperties
のキーワードを確認しました。
これに以下を追加します。

スキーマ
{ "$id": "https://example.com/entry-schema", "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "description": "JSON Schema for an fstab entry", "type": "object", "required": [ "storage" ], "properties": { "storage": { "type": "object", "oneOf": [ { "$ref": "#/$defs/diskDevice" }, { "$ref": "#/$defs/diskUUID" }, { "$ref": "#/$defs/nfs" }, { "$ref": "#/$defs/tmpfs" } ] } }, "$defs": { "diskDevice": {}, "diskUUID": {}, "nfs": {}, "tmpfs": {} }}
エントリの制約
それでは、このスケルトンを拡張して、いくつかのプロパティに制約を追加してみましょう。
fstype
キーは、enum
検証キーワードを使用します。options
キーは以下を使用します。type
検証キーワード(上記参照)。minItems
検証キーワード。items
検証キーワード。uniqueItems
検証キーワード。- これらを合わせると、「
options
は配列でなければならず、その中のアイテムは文字列でなければならず、少なくとも1つのアイテムが存在し、すべてのアイテムは一意でなければならない」という意味になります。
readonly
キーがあります。
これらの制約を追加すると、スキーマは次のようになります。

スキーマ
{ "$id": "https://example.com/entry-schema", "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "description": "JSON Schema for an fstab entry", "type": "object", "required": [ "storage" ], "properties": { "storage": { "type": "object", "oneOf": [ { "$ref": "#/$defs/diskDevice" }, { "$ref": "#/$defs/diskUUID" }, { "$ref": "#/$defs/nfs" }, { "$ref": "#/$defs/tmpfs" } ] }, "fstype": { "enum": [ "ext3", "ext4", "btrfs" ] }, "options": { "type": "array", "minItems": 1, "items": { "type": "string" }, "uniqueItems": true }, "readonly": { "type": "boolean" } }, "$defs": { "diskDevice": {}, "diskUUID": {}, "nfs": {}, "tmpfs": {} }}
diskDevice
定義
ここでは、新しいキーワードが1つ導入されています。
pattern
検証キーワードは、device
キーが /dev で始まる絶対パスでなければならないことを示します。
{ "diskDevice": { "properties": { "type": { "enum": [ "disk" ] }, "device": { "type": "string", "pattern": "^/dev/[^/]+(/[^/]+)*$" } }, "required": [ "type", "device" ], "additionalProperties": false }}
diskUUID
定義
ここでは新しいキーワードは導入されていません。
新しいキーとしてlabel
があり、pattern
検証キーワードは、それが有効なUUIDでなければならないことを示しています。
{ "diskUUID": { "properties": { "type": { "enum": [ "disk" ] }, "label": { "type": "string", "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" } }, "required": [ "type", "label" ], "additionalProperties": false }}
nfs
定義
別の新しいキーワードが見つかりました。
{ "nfs": { "properties": { "type": { "enum": [ "nfs" ] }, "remotePath": { "type": "string", "pattern": "^(/[^/]+)+$" }, "server": { "type": "string", "oneOf": [ { "format": "hostname" }, { "format": "ipv4" }, { "format": "ipv6" } ] } }, "required": [ "type", "server", "remotePath" ], "additionalProperties": false }}
tmpfs
定義
最後の定義では、2つの新しいキーワードが導入されています。
minimum
検証キーワード。maximum
検証キーワード。- これらを合わせると、サイズは16から512(両端含む)の間である必要があります。
{ "tmpfs": { "properties": { "type": { "enum": [ "tmpfs" ] }, "sizeInMB": { "type": "integer", "minimum": 16, "maximum": 512 } }, "required": [ "type", "sizeInMB" ], "additionalProperties": false }}
完全なエントリスキーマ
結果として得られるスキーマはかなり大きくなります。

スキーマ
{ "$id": "https://example.com/entry-schema", "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "description": "JSON Schema for an fstab entry", "type": "object", "required": [ "storage" ], "properties": { "storage": { "type": "object", "oneOf": [ { "$ref": "#/$defs/diskDevice" }, { "$ref": "#/$defs/diskUUID" }, { "$ref": "#/$defs/nfs" }, { "$ref": "#/$defs/tmpfs" } ] }, "fstype": { "enum": [ "ext3", "ext4", "btrfs" ] }, "options": { "type": "array", "minItems": 1, "items": { "type": "string" }, "uniqueItems": true }, "readonly": { "type": "boolean" } }, "$defs": { "diskDevice": { "properties": { "type": { "enum": [ "disk" ] }, "device": { "type": "string", "pattern": "^/dev/[^/]+(/[^/]+)*$" } }, "required": [ "type", "device" ], "additionalProperties": false }, "diskUUID": { "properties": { "type": { "enum": [ "disk" ] }, "label": { "type": "string", "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" } }, "required": [ "type", "label" ], "additionalProperties": false }, "nfs": { "properties": { "type": { "enum": [ "nfs" ] }, "remotePath": { "type": "string", "pattern": "^(/[^/]+)+$" }, "server": { "type": "string", "oneOf": [ { "format": "hostname" }, { "format": "ipv4" }, { "format": "ipv6" } ] } }, "required": [ "type", "server", "remotePath" ], "additionalProperties": false }, "tmpfs": { "properties": { "type": { "enum": [ "tmpfs" ] }, "sizeInMB": { "type": "integer", "minimum": 16, "maximum": 512 } }, "required": [ "type", "sizeInMB" ], "additionalProperties": false } }}
fstab
スキーマでのentry
スキーマの参照
話を元に戻すと、演習の最初に空けておいたキーに、エントリースキーマを追加するために$ref
キーワードを使用します。

スキーマ
{ "$id": "https://example.com/fstab", "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "type": "object", "required": [ "/" ], "properties": { "/": { "$ref": "https://example.com/entry-schema" } }, "patternProperties": { "^(/[^/]+)+$": { "$ref": "https://example.com/entry-schema" } }, "additionalProperties": false}