При создании описания политики можно использовать шаблонизатор Ginger, интегрированный в компилятор nk-psl-gen-c
. Для управления шаблонизатором нужно использовать параметры компилятора nk-psl-gen-c
или параметры CMake-команд build_kos_qemu_image()
и build_kos_hw_image()
.
PSL-шаблон Ginger представляет собой PSL-файл, который, помимо деклараций на языке PSL, содержит синтаксические конструкции шаблонизатора Ginger. Такие файлы, как security.psl.in
, security.psl
, core.psl
, являются PSL-шаблонами Ginger, если в них содержаться синтаксические конструкции шаблонизатора Ginger. (Файл security.psl.in
одновременно является PSL-шаблоном в другом контексте, так как в этом файле могут использоваться макросы и переменные, не связанные с шаблонизатором Ginger.)
Описание синтаксических конструкций шаблонизатора Ginger приведено в официальной документации на этот шаблонизатор. Например, можно использовать макросы.
Пример определения макроса:
{% macro VMMSafe(src) %}
match method=Allocate {
match src={{ src }} { grant () }
}
{% endmacro %}
Пример вызова макроса:
{{ VMMSafe(["Einit"]) }}
В результате этого вызова будет создана следующая конструкция:
match method=Allocate {
match src=Einit { grant () }
}
Пример определения макроса с циклами:
{% macro VMMSafe(srcs) %}
{% for method in ["Allocate", "Commit", "Decommit"] %}
match method={{ method }} {
{% for src in srcs %}
match src={{ src }} { grant () }
{% endfor %}
}
{% endfor %}
{% endmacro %}
Пример конструкции с вызовом макроса:
match endpoint=vmm.VMM {
{{ VMMSafe(["Einit", "client.Client", "consumer.Consumer",
"kl.bc.BlobContainer", "kl.core.NameServer",
"kl.VfsEntity", "scm.Producer", "execution_manager.ExecMgrEntity",
"scm.SecurityConfigMgrEntity", "kl.drivers.ATA", "kl.drivers.PCIE"]) }}
}
В результате раскрытия макроса в этой конструкции будет создана следующая конструкция:
match endpoint=vmm.VMM {
match method=Allocate {
match src=Einit { grant () }
match src=client.Client { grant () }
match src=consumer.Consumer { grant () }
match src=kl.bc.BlobContainer { grant () }
match src=kl.core.NameServer { grant () }
match src=kl.VfsEntity { grant () }
match src=scm.Producer { grant () }
match src=execution_manager.ExecMgrEntity { grant () }
match src=scm.SecurityConfigMgrEntity { grant () }
match src=kl.drivers.ATA { grant () }
match src=kl.drivers.PCIE { grant () }
}
match method=Commit {
match src=Einit { grant () }
match src=client.Client { grant () }
match src=consumer.Consumer { grant () }
match src=kl.bc.BlobContainer { grant () }
match src=kl.core.NameServer { grant () }
match src=kl.VfsEntity { grant () }
match src=scm.Producer { grant () }
match src=execution_manager.ExecMgrEntity { grant () }
match src=scm.SecurityConfigMgrEntity { grant () }
match src=kl.drivers.ATA { grant () }
match src=kl.drivers.PCIE { grant () }
}
match method=Decommit {
match src=Einit { grant () }
match src=client.Client { grant () }
match src=consumer.Consumer { grant () }
match src=kl.bc.BlobContainer { grant () }
match src=kl.core.NameServer { grant () }
match src=kl.VfsEntity { grant () }
match src=scm.Producer { grant () }
match src=execution_manager.ExecMgrEntity { grant () }
match src=scm.SecurityConfigMgrEntity { grant () }
match src=kl.drivers.ATA { grant () }
match src=kl.drivers.PCIE { grant () }
}
}
В PSL-шаблонах Ginger можно использовать комментарии:
{# Комментарий, который будет удален при раскрытии шаблона. #}
Также в PSL-шаблонах Ginger можно использовать конструкцию включения файла.
Пример конструкции включения файла:
{% include "defs.ginger" %}
Файл defs.ginger
может содержать, например, определения макросов, используемых в PSL-шаблоне Ginger. Этот файл должен находится в одной директории с PSL-шаблоном Ginger, который содержит эту конструкцию.