pve-installer/country.pl
Christoph Heiss dc401eb3f0 country.pl: generate final structure as json at build time directly
Currently, we generate a custom-format `country.dat` at build time,
which we then ship with the installer. In the live environment, this
then gets parsed (via regexes) into another format and is finally
written out as JSON for e.g. the TUI and auto-installer to consume.

Instead, skip the intermediate format completely and just generate the
final data structure as JSON at build time.

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
2024-12-10 18:00:24 +01:00

145 lines
3.4 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
use PVE::Tools;
use JSON qw(from_json to_json);
# Generates a
#
# - country code => name/kmap/mirror
# - name => country code
#
# mapping for each defined country
my sub generate_country_mappings {
my ($country_codes, $defmap, $mirrors) = @_;
my ($countries, $countryhash) = ({}, {});
foreach my $cc (sort keys %$country_codes) {
my $name = $country_codes->{$cc};
my $kmap = $defmap->{$cc} || '';
my $mirror = $mirrors->{$cc} || '';
$countries->{$cc} = {
name => $name,
kmap => $kmap,
mirror => $mirror,
};
$countryhash->{lc($name)} = $cc;
}
return ($countries, $countryhash);
}
# we need mappings for X11, console, and kvm vnc
# LC(-LC)? => [DESC, kvm, console, X11, X11variant]
my sub generate_keymaps {
my ($country_codes) = @_;
my ($kmap, $kmaphash) = ({}, {});
my $keymaps = PVE::Tools::kvmkeymaps();
foreach my $km (sort keys %$keymaps) {
my ($name, $kvm, $console, $x11, $x11var) = @{$keymaps->{$km}};
if ($km =~m/^([a-z][a-z])-([a-z][a-z])$/i) {
defined ($country_codes->{$2}) || die "undefined country code '$2'";
} else {
defined ($country_codes->{$km}) || die "undefined country code '$km'";
}
$x11var = '' if !defined ($x11var);
$kmap->{$km} = {
name => $name,
kvm => $kvm,
console => $console,
x11 => $x11,
x11var => $x11var,
};
$kmaphash->{$name} = $km;
}
return ($kmap, $kmaphash);
}
my sub parse_zoneinfo {
my ($countries) = @_;
my $zonefn = "/usr/share/zoneinfo/zone.tab";
open (my $ZONE_TAB_FH, '<', "$zonefn") || die "unable to open '$zonefn' - $!\n";
my ($zones, $cczones) = ({}, {});
while (defined (my $line = <$ZONE_TAB_FH>)) {
next if $line =~ m/^\s*(?:#|$)/;
if ($line =~ m|^([A-Z][A-Z])\s+\S+\s+(([^/]+)/\S+)\s|) {
my $cc = lc($1);
$cczones->{$cc}->{$2} = 1;
$countries->{$cc}->{zone} = $2 if !defined ($countries->{$cc}->{zone});
$zones->{$2} = 1;
}
}
close ($ZONE_TAB_FH);
return ($zones, $cczones);
}
# country codes from:
my $country_codes_file = "/usr/share/iso-codes/json/iso_3166-1.json";
my $iso_3166_codes = from_json(PVE::Tools::file_get_contents($country_codes_file, 64 * 1024));
my $country_codes = { map { lc($_->{'alpha_2'}) => $_->{'common_name'} // $_->{'name'} } @{$iso_3166_codes->{'3166-1'}} };
my $defmap = {
'us' => 'en-us',
'be' => 'fr-be',
'br' => 'pt-br',
'ca' => 'en-us',
'dk' => 'dk',
'nl' => 'en-us', # most Dutch people use US layout
'fi' => 'fi',
'fr' => 'fr',
'de' => 'de',
'at' => 'de',
'hu' => 'hu',
'is' => 'is',
'it' => 'it',
'va' => 'it',
'jp' => 'jp',
'lt' => 'lt',
'mk' => 'mk',
'no' => 'no',
'pl' => 'pl',
'pt' => 'pt',
'si' => 'si',
'es' => 'es',
'gi' => 'es',
'ch' => 'de-ch',
'gb' => 'en-gb',
'lu' => 'fr-ch',
'li' => 'de-ch',
};
my $mirrors = PVE::Tools::debmirrors();
foreach my $cc (keys %$mirrors) {
die "undefined country code '$cc'" if !defined ($country_codes->{$cc});
}
my ($countries, $countryhash) = generate_country_mappings($country_codes, $defmap, $mirrors);
my ($kmap, $kmaphash) = generate_keymaps($country_codes);
my ($zones, $cczones) = parse_zoneinfo($countries);
my $locale_info = {
country => $countries,
countryhash => $countryhash,
kmap => $kmap,
kmaphash => $kmaphash,
zones => $zones,
cczones => $cczones,
};
my $json = to_json($locale_info, { utf8 => 1, canonical => 1 });
print $json;