[PATCH 0/2] po: handle translatin of polkit policy file strings

There was a proposal https://gitlab.com/libvirt/libvirt/-/merge_requests/387 to add translations for the polkit files. In reviewing this we came to the conclusion the approach was undesirable. After getting misled by a Debian/Ubuntu specific downstream only patch to polkit which auto-translated polkit files at runtime, this implements the manual approach of merging translations into the polkit files at build time. Daniel P. Berrangé (2): po: add its rules for translating polkit file strings remote: apply translations to polkit files meson.build | 5 +++++ po/POTFILES | 2 ++ po/its/polkit.its | 8 ++++++++ po/its/polkit.loc | 6 ++++++ po/meson.build | 3 +-- src/access/meson.build | 18 ++++++++++++++---- .../{libvirtd.policy => libvirtd.policy.in} | 0 src/remote/meson.build | 13 ++++++++----- 8 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 po/its/polkit.its create mode 100644 po/its/polkit.loc rename src/remote/{libvirtd.policy => libvirtd.policy.in} (100%) -- 2.46.0

xgettext / msgfmt have generic support for extracting / merging strings in XML files, however, they need to be told something about the schema to know which fields are translatable. This is done by providing 'its' rules. Usually the 'its' rules would be shipped in a -devel package of the app which owns the schema definition, but polkit does not do this. Thus libvirt (and other apps) must ship their own local 'its' rules for polkit. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- po/its/polkit.its | 8 ++++++++ po/its/polkit.loc | 6 ++++++ po/meson.build | 1 + 3 files changed, 15 insertions(+) create mode 100644 po/its/polkit.its create mode 100644 po/its/polkit.loc diff --git a/po/its/polkit.its b/po/its/polkit.its new file mode 100644 index 0000000000..1c37e6bee7 --- /dev/null +++ b/po/its/polkit.its @@ -0,0 +1,8 @@ +<?xml version="1.0"?> +<its:rules xmlns:its="http://www.w3.org/2005/11/its" + version="2.0"> + <its:translateRule selector="//*" translate="no"/> + <its:translateRule selector="//action/description | + //action/message" + translate="yes"/> +</its:rules> diff --git a/po/its/polkit.loc b/po/its/polkit.loc new file mode 100644 index 0000000000..c7427ec672 --- /dev/null +++ b/po/its/polkit.loc @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<locatingRules> + <locatingRule name="polkit policy" pattern="*.policy"> + <documentRule localName="policyconfig" target="polkit.its"/> + </locatingRule> +</locatingRules> diff --git a/po/meson.build b/po/meson.build index 592b254447..126eeabe17 100644 --- a/po/meson.build +++ b/po/meson.build @@ -14,6 +14,7 @@ i18n.gettext( '--package-version=@0@'.format(meson.project_version()), '--sort-output', ], + data_dirs: meson.current_source_dir() ) potfiles_dep = [ -- 2.46.0

The 'description' and 'message' fields in polkit policy files should be translated into the user's chosen language. xgettext is told to search in both and source and build dirs by meson. Unfortunately a bug in xgettext means that when it searches for built files in XML format, it'll trigger a warning message due to failure to load the generated file from the source dir: xgettext: cannot read ..snip../libvirt/src/access/org.libvirt.api.policy: failed to load external entity "..snip../libvirt/src/access/org.libvirt.api.policy" This is harmless since it then goes on to try the build dir and succeeds, but will pollute the output of 'ninja libvirt-pot' Related: https://gitlab.com/libvirt/libvirt/-/merge_requests/387 Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- meson.build | 5 +++++ po/POTFILES | 2 ++ po/meson.build | 2 -- src/access/meson.build | 18 ++++++++++++++---- .../{libvirtd.policy => libvirtd.policy.in} | 0 src/remote/meson.build | 13 ++++++++----- 6 files changed, 29 insertions(+), 11 deletions(-) rename src/remote/{libvirtd.policy => libvirtd.policy.in} (100%) diff --git a/meson.build b/meson.build index ca1b915737..0d0bd03a2a 100644 --- a/meson.build +++ b/meson.build @@ -15,6 +15,10 @@ if meson.version().version_compare('>=0.64.0') fs = import('fs') endif +i18n = import('i18n') + +po_dir = meson.source_root() / 'po' + # figure out if we are building from git git = run_command('test', '-e', '.git', check: false).returncode() == 0 @@ -114,6 +118,7 @@ localedir = prefix / get_option('localedir') mandir = prefix / get_option('mandir') sbindir = prefix / get_option('sbindir') sharedstatedir = prefix / get_option('sharedstatedir') +polkitactiondir = datadir / 'polkit-1' / 'actions' docdir = get_option('docdir') if docdir == '' diff --git a/po/POTFILES b/po/POTFILES index 3514aa3dca..ff6f3763d5 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,6 +1,7 @@ src/access/viraccessapicheck.c src/access/viraccessapichecklxc.c src/access/viraccessapicheckqemu.c +src/access/org.libvirt.api.policy.in src/admin/admin_client.h src/admin/admin_server_dispatch_stubs.h src/remote/remote_client_bodies.h @@ -201,6 +202,7 @@ src/qemu/qemu_validate.c src/qemu/qemu_vhost_user.c src/qemu/qemu_vhost_user_gpu.c src/qemu/qemu_virtiofs.c +src/remote/libvirtd.policy.in src/remote/remote_daemon.c src/remote/remote_daemon_config.c src/remote/remote_daemon_dispatch.c diff --git a/po/meson.build b/po/meson.build index 126eeabe17..d8ace5373e 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,5 +1,3 @@ -i18n = import('i18n') - i18n.gettext( meson.project_name(), args: [ diff --git a/src/access/meson.build b/src/access/meson.build index fc5ba5b342..42aa5c7225 100644 --- a/src/access/meson.build +++ b/src/access/meson.build @@ -66,14 +66,24 @@ if conf.has('WITH_POLKIT') access_sources += access_polkit_sources if conf.has('WITH_LIBVIRTD') - custom_target( - 'org.libvirt.api.policy', + polgen = custom_target( + 'org.libvirt.api.policy.in', input: access_perm_h, - output: 'org.libvirt.api.policy', + output: 'org.libvirt.api.policy.in', command: [ meson_python_prog, python3_prog, genpolkit_prog, '@INPUT@' ], capture: true, + build_by_default: true, + install: true, + install_dir: polkitactiondir, + ) + + i18n.merge_file( + input: polgen, + output: 'org.libvirt.api.policy', + po_dir: po_dir, + data_dirs: [po_dir], install: true, - install_dir: datadir / 'polkit-1' / 'actions', + install_dir: polkitdir / 'actions', ) endif endif diff --git a/src/remote/libvirtd.policy b/src/remote/libvirtd.policy.in similarity index 100% rename from src/remote/libvirtd.policy rename to src/remote/libvirtd.policy.in diff --git a/src/remote/meson.build b/src/remote/meson.build index 831acaaa01..9f66ee2e1c 100644 --- a/src/remote/meson.build +++ b/src/remote/meson.build @@ -294,12 +294,15 @@ if conf.has('WITH_REMOTE') endif if conf.has('WITH_POLKIT') - polkitdir = datadir / 'polkit-1' - install_data( - 'libvirtd.policy', - install_dir: polkitdir / 'actions', - rename: [ 'org.libvirt.unix.policy' ], + i18n.merge_file( + input: 'libvirtd.policy.in', + output: 'org.libvirt.unix.policy', + po_dir: po_dir, + data_dirs: [po_dir], + install: true, + install_dir: polkitactiondir, ) + install_data( 'libvirtd.rules', install_dir: polkitdir / 'rules.d', -- 2.46.0

On Thu, Dec 19, 2024 at 05:29:07PM +0000, Daniel P. Berrangé wrote:
The 'description' and 'message' fields in polkit policy files should be translated into the user's chosen language. xgettext is told to search in both and source and build dirs by meson.
Unfortunately a bug in xgettext means that when it searches for built files in XML format, it'll trigger a warning message due to failure to load the generated file from the source dir:
xgettext: cannot read ..snip../libvirt/src/access/org.libvirt.api.policy: failed to load external entity "..snip../libvirt/src/access/org.libvirt.api.policy"
This is harmless since it then goes on to try the build dir and succeeds, but will pollute the output of 'ninja libvirt-pot'
Related: https://gitlab.com/libvirt/libvirt/-/merge_requests/387 Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> --- meson.build | 5 +++++ po/POTFILES | 2 ++ po/meson.build | 2 -- src/access/meson.build | 18 ++++++++++++++---- .../{libvirtd.policy => libvirtd.policy.in} | 0 src/remote/meson.build | 13 ++++++++----- 6 files changed, 29 insertions(+), 11 deletions(-) rename src/remote/{libvirtd.policy => libvirtd.policy.in} (100%)
diff --git a/meson.build b/meson.build index ca1b915737..0d0bd03a2a 100644 --- a/meson.build +++ b/meson.build @@ -15,6 +15,10 @@ if meson.version().version_compare('>=0.64.0') fs = import('fs') endif
+i18n = import('i18n') + +po_dir = meson.source_root() / 'po' + # figure out if we are building from git
git = run_command('test', '-e', '.git', check: false).returncode() == 0 @@ -114,6 +118,7 @@ localedir = prefix / get_option('localedir') mandir = prefix / get_option('mandir') sbindir = prefix / get_option('sbindir') sharedstatedir = prefix / get_option('sharedstatedir') +polkitactiondir = datadir / 'polkit-1' / 'actions'
docdir = get_option('docdir') if docdir == '' diff --git a/po/POTFILES b/po/POTFILES index 3514aa3dca..ff6f3763d5 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,6 +1,7 @@ src/access/viraccessapicheck.c src/access/viraccessapichecklxc.c src/access/viraccessapicheckqemu.c +src/access/org.libvirt.api.policy.in src/admin/admin_client.h src/admin/admin_server_dispatch_stubs.h src/remote/remote_client_bodies.h @@ -201,6 +202,7 @@ src/qemu/qemu_validate.c src/qemu/qemu_vhost_user.c src/qemu/qemu_vhost_user_gpu.c src/qemu/qemu_virtiofs.c +src/remote/libvirtd.policy.in src/remote/remote_daemon.c src/remote/remote_daemon_config.c src/remote/remote_daemon_dispatch.c diff --git a/po/meson.build b/po/meson.build index 126eeabe17..d8ace5373e 100644 --- a/po/meson.build +++ b/po/meson.build @@ -1,5 +1,3 @@ -i18n = import('i18n') - i18n.gettext( meson.project_name(), args: [ diff --git a/src/access/meson.build b/src/access/meson.build index fc5ba5b342..42aa5c7225 100644 --- a/src/access/meson.build +++ b/src/access/meson.build @@ -66,14 +66,24 @@ if conf.has('WITH_POLKIT') access_sources += access_polkit_sources
if conf.has('WITH_LIBVIRTD') - custom_target( - 'org.libvirt.api.policy', + polgen = custom_target( + 'org.libvirt.api.policy.in', input: access_perm_h, - output: 'org.libvirt.api.policy', + output: 'org.libvirt.api.policy.in', command: [ meson_python_prog, python3_prog, genpolkit_prog, '@INPUT@' ], capture: true, + build_by_default: true, + install: true, + install_dir: polkitactiondir, + )
These two install lines should not have been present here
+ + i18n.merge_file( + input: polgen, + output: 'org.libvirt.api.policy', + po_dir: po_dir, + data_dirs: [po_dir], install: true, - install_dir: datadir / 'polkit-1' / 'actions', + install_dir: polkitdir / 'actions',
and this should have referenced 'polkitactiondir', so will fix these when pushing
) endif endif diff --git a/src/remote/libvirtd.policy b/src/remote/libvirtd.policy.in similarity index 100% rename from src/remote/libvirtd.policy rename to src/remote/libvirtd.policy.in diff --git a/src/remote/meson.build b/src/remote/meson.build index 831acaaa01..9f66ee2e1c 100644 --- a/src/remote/meson.build +++ b/src/remote/meson.build @@ -294,12 +294,15 @@ if conf.has('WITH_REMOTE') endif
if conf.has('WITH_POLKIT') - polkitdir = datadir / 'polkit-1' - install_data( - 'libvirtd.policy', - install_dir: polkitdir / 'actions', - rename: [ 'org.libvirt.unix.policy' ], + i18n.merge_file( + input: 'libvirtd.policy.in', + output: 'org.libvirt.unix.policy', + po_dir: po_dir, + data_dirs: [po_dir], + install: true, + install_dir: polkitactiondir, ) + install_data( 'libvirtd.rules', install_dir: polkitdir / 'rules.d', -- 2.46.0
With regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On a Thursday in 2024, Daniel P. Berrangé wrote:
There was a proposal
https://gitlab.com/libvirt/libvirt/-/merge_requests/387
to add translations for the polkit files. In reviewing this we came to the conclusion the approach was undesirable. After getting misled by a Debian/Ubuntu specific downstream only patch to polkit which auto-translated polkit files at runtime, this implements the manual approach of merging translations into the polkit files at build time.
Daniel P. Berrangé (2): po: add its rules for translating polkit file strings remote: apply translations to polkit files
meson.build | 5 +++++ po/POTFILES | 2 ++ po/its/polkit.its | 8 ++++++++ po/its/polkit.loc | 6 ++++++ po/meson.build | 3 +-- src/access/meson.build | 18 ++++++++++++++---- .../{libvirtd.policy => libvirtd.policy.in} | 0 src/remote/meson.build | 13 ++++++++----- 8 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 po/its/polkit.its create mode 100644 po/its/polkit.loc rename src/remote/{libvirtd.policy => libvirtd.policy.in} (100%)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Daniel P. Berrangé
-
Ján Tomko