From d0571ec17bde1d951b3057459337f83bb7df8ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Thu, 12 Jun 2025 14:53:27 +0200 Subject: [PATCH 1/4] Configure the console font Unfortunately "systemd-firstboot" does not support configuring the font so we need to write it directly into the /etc/vconsole.conf configuration file. --- live/src/config.sh | 3 +++ rust/agama-locale-data/src/language.rs | 3 ++- rust/agama-locale-data/src/ranked.rs | 13 +++++++++++++ rust/agama-server/src/l10n/model.rs | 21 ++++++++++++++++++++- rust/agama-server/src/l10n/model/locale.rs | 17 ++++++++++++++++- rust/package/agama.changes | 6 ++++++ 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/live/src/config.sh b/live/src/config.sh index e569f55584..6729253f90 100644 --- a/live/src/config.sh +++ b/live/src/config.sh @@ -91,6 +91,9 @@ systemctl disable snapper-timeline.timer systemctl disable YaST2-Firstboot.service systemctl disable YaST2-Second-Stage.service +# the "eurlatgr" is the default font for the English locale +echo -e "\nFONT=eurlatgr.psfu" >> /etc/vconsole.conf + ### setup dracut for live system arch=$(uname -m) # keep in sync with ISO Volume ID set in the fix_bootconfig script diff --git a/rust/agama-locale-data/src/language.rs b/rust/agama-locale-data/src/language.rs index d91885f0f4..36d5b51ae3 100644 --- a/rust/agama-locale-data/src/language.rs +++ b/rust/agama-locale-data/src/language.rs @@ -20,7 +20,7 @@ use serde::Deserialize; -use crate::ranked::{RankedLocales, RankedTerritories}; +use crate::ranked::{RankedConsoleFonts, RankedLocales, RankedTerritories}; #[derive(Debug, Deserialize)] pub struct Language { @@ -29,6 +29,7 @@ pub struct Language { pub territories: RankedTerritories, pub locales: RankedLocales, pub names: crate::localization::Localization, + pub consolefonts: RankedConsoleFonts, } #[derive(Debug, Deserialize)] diff --git a/rust/agama-locale-data/src/ranked.rs b/rust/agama-locale-data/src/ranked.rs index 01b9235928..f8008a4b87 100644 --- a/rust/agama-locale-data/src/ranked.rs +++ b/rust/agama-locale-data/src/ranked.rs @@ -61,3 +61,16 @@ pub struct RankedLocales { #[serde(default)] pub locale: Vec, } + +#[derive(Debug, Deserialize)] +pub struct RankedConsoleFont { + #[serde(rename(deserialize = "consolefontId"))] + pub id: String, + pub rank: u16, +} + +#[derive(Debug, Deserialize)] +pub struct RankedConsoleFonts { + #[serde(default)] + pub consolefont: Vec, +} diff --git a/rust/agama-server/src/l10n/model.rs b/rust/agama-server/src/l10n/model.rs index 470f59c12a..4513563bc9 100644 --- a/rust/agama-server/src/l10n/model.rs +++ b/rust/agama-server/src/l10n/model.rs @@ -19,7 +19,8 @@ // find current contact information at www.suse.com. use std::env; -use std::io; +use std::fs::OpenOptions; +use std::io::{self, Write}; use std::process::Command; use std::time::Duration; @@ -244,6 +245,7 @@ impl L10n { // TODO: what should be returned value for commit? pub fn commit(&self) -> Result<(), LocaleError> { const ROOT: &str = "/mnt"; + const VCONSOLE_CONF: &str = "/etc/vconsole.conf"; let locale = self.locales.first().cloned().unwrap_or_default(); let mut cmd = Command::new("/usr/bin/systemd-firstboot"); @@ -263,6 +265,23 @@ impl L10n { let output = cmd.output()?; tracing::info!("{:?}", &output); + // unfortunately the console font cannot be set via the "systemd-firstboot" tool, + // we need to write it directly to the config file + let locale = self.locales_db.entries().iter().find(|l| l.id == locale); + if let Some(entry) = locale { + let font = &entry.consolefont; + + if !font.is_empty() { + // the font entry is missing in a file created by "systemd-firstboot", just append it at the end + let mut file = OpenOptions::new() + .append(true) + .open(format!("{}{}", ROOT, VCONSOLE_CONF))?; + + tracing::info!("Configuring console font \"{:?}\"", font); + writeln!(file, "\nFONT={}.psfu", font)?; + } + } + Ok(()) } diff --git a/rust/agama-server/src/l10n/model/locale.rs b/rust/agama-server/src/l10n/model/locale.rs index d2345b2bd2..9d3d041251 100644 --- a/rust/agama-server/src/l10n/model/locale.rs +++ b/rust/agama-server/src/l10n/model/locale.rs @@ -21,7 +21,7 @@ //! This module provides support for reading the locales database. use crate::error::Error; -use agama_locale_data::LocaleId; +use agama_locale_data::{ranked::RankedConsoleFont, LocaleId}; use anyhow::Context; use serde::Serialize; use serde_with::{serde_as, DisplayFromStr}; @@ -38,6 +38,8 @@ pub struct LocaleEntry { pub language: String, /// Localized territory name (e.g., "Spain", "España", etc.) pub territory: String, + /// Console font + pub consolefont: String, } /// Represents the locales database. @@ -110,7 +112,20 @@ impl LocalesDatabase { id: code.clone(), language: language_label, territory: territory_label, + consolefont: language + .consolefonts + .consolefont + .first() + .unwrap_or(&RankedConsoleFont { + id: String::new(), + rank: 0, + }) + .id + .clone(), }; + + tracing::info!("Using locale data {:?}", entry); + result.push(entry) } diff --git a/rust/package/agama.changes b/rust/package/agama.changes index 0418f82787..51fccab681 100644 --- a/rust/package/agama.changes +++ b/rust/package/agama.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Jun 12 12:39:03 UTC 2025 - Ladislav Slezák + +- Configure the console font so the non-ASCII characters are + displayed properly (bsc#1239462) + ------------------------------------------------------------------- Wed Jun 11 13:12:12 UTC 2025 - Imobach Gonzalez Sosa From 1f5dc32e3e42c9c194b9bc04393372980e861a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Fri, 13 Jun 2025 10:07:16 +0200 Subject: [PATCH 2/4] Use Option for the console font --- rust/agama-server/src/l10n/model.rs | 4 +--- rust/agama-server/src/l10n/model/locale.rs | 20 ++++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/rust/agama-server/src/l10n/model.rs b/rust/agama-server/src/l10n/model.rs index 4513563bc9..28ae3947ee 100644 --- a/rust/agama-server/src/l10n/model.rs +++ b/rust/agama-server/src/l10n/model.rs @@ -269,9 +269,7 @@ impl L10n { // we need to write it directly to the config file let locale = self.locales_db.entries().iter().find(|l| l.id == locale); if let Some(entry) = locale { - let font = &entry.consolefont; - - if !font.is_empty() { + if let Some(font) = &entry.consolefont { // the font entry is missing in a file created by "systemd-firstboot", just append it at the end let mut file = OpenOptions::new() .append(true) diff --git a/rust/agama-server/src/l10n/model/locale.rs b/rust/agama-server/src/l10n/model/locale.rs index 9d3d041251..5f63568654 100644 --- a/rust/agama-server/src/l10n/model/locale.rs +++ b/rust/agama-server/src/l10n/model/locale.rs @@ -21,7 +21,7 @@ //! This module provides support for reading the locales database. use crate::error::Error; -use agama_locale_data::{ranked::RankedConsoleFont, LocaleId}; +use agama_locale_data::LocaleId; use anyhow::Context; use serde::Serialize; use serde_with::{serde_as, DisplayFromStr}; @@ -39,7 +39,7 @@ pub struct LocaleEntry { /// Localized territory name (e.g., "Spain", "España", etc.) pub territory: String, /// Console font - pub consolefont: String, + pub consolefont: Option, } /// Represents the locales database. @@ -108,20 +108,16 @@ impl LocalesDatabase { .or_else(|| names.name_for(DEFAULT_LANG)) .unwrap_or(territory.id.to_string()); + let consolefont = match language.consolefonts.consolefont.first() { + Some(font) => Some(font.id.clone()), + None => None, + }; + let entry = LocaleEntry { id: code.clone(), language: language_label, territory: territory_label, - consolefont: language - .consolefonts - .consolefont - .first() - .unwrap_or(&RankedConsoleFont { - id: String::new(), - rank: 0, - }) - .id - .clone(), + consolefont, }; tracing::info!("Using locale data {:?}", entry); From 539cb89048e360a71f975a782d496bbadfb2e5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Fri, 13 Jun 2025 10:39:51 +0200 Subject: [PATCH 3/4] Added find_locale() method --- rust/agama-server/src/l10n/model.rs | 3 +-- rust/agama-server/src/l10n/model/locale.rs | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/rust/agama-server/src/l10n/model.rs b/rust/agama-server/src/l10n/model.rs index 28ae3947ee..c5b40e0f78 100644 --- a/rust/agama-server/src/l10n/model.rs +++ b/rust/agama-server/src/l10n/model.rs @@ -267,8 +267,7 @@ impl L10n { // unfortunately the console font cannot be set via the "systemd-firstboot" tool, // we need to write it directly to the config file - let locale = self.locales_db.entries().iter().find(|l| l.id == locale); - if let Some(entry) = locale { + if let Some(entry) = self.locales_db.find_locale(&locale) { if let Some(font) = &entry.consolefont { // the font entry is missing in a file created by "systemd-firstboot", just append it at the end let mut file = OpenOptions::new() diff --git a/rust/agama-server/src/l10n/model/locale.rs b/rust/agama-server/src/l10n/model/locale.rs index 5f63568654..08e1fdc55e 100644 --- a/rust/agama-server/src/l10n/model/locale.rs +++ b/rust/agama-server/src/l10n/model/locale.rs @@ -79,6 +79,11 @@ impl LocalesDatabase { &self.locales } + /// Find the locale in the database + pub fn find_locale(&self, locale: &LocaleId) -> Option<&LocaleEntry> { + self.locales.iter().find(|l| l.id == *locale) + } + /// Gets the supported locales information. /// /// * `ui_language`: language to use in the translations. From ab5169e3e0c5cdbe8e01ce7bbf8c00f8b6417d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Fri, 13 Jun 2025 14:41:09 +0200 Subject: [PATCH 4/4] Review fixes --- rust/agama-server/src/l10n/model/locale.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rust/agama-server/src/l10n/model/locale.rs b/rust/agama-server/src/l10n/model/locale.rs index 08e1fdc55e..43c3cd02de 100644 --- a/rust/agama-server/src/l10n/model/locale.rs +++ b/rust/agama-server/src/l10n/model/locale.rs @@ -80,6 +80,8 @@ impl LocalesDatabase { } /// Find the locale in the database + /// + /// * `locale`: the language to find pub fn find_locale(&self, locale: &LocaleId) -> Option<&LocaleEntry> { self.locales.iter().find(|l| l.id == *locale) } @@ -113,10 +115,11 @@ impl LocalesDatabase { .or_else(|| names.name_for(DEFAULT_LANG)) .unwrap_or(territory.id.to_string()); - let consolefont = match language.consolefonts.consolefont.first() { - Some(font) => Some(font.id.clone()), - None => None, - }; + let consolefont = language + .consolefonts + .consolefont + .first() + .map(|f| f.id.clone()); let entry = LocaleEntry { id: code.clone(),