From 7bd803779e34332eda9220670127e8bc72b7e1fa Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 16 2023 06:12:56 +0000 Subject: import dnf-plugins-core-4.0.21-19.el8_8 --- diff --git a/SOURCES/0024-Update-translations-RHEL-8.7.patch b/SOURCES/0024-Update-translations-RHEL-8.7.patch deleted file mode 100644 index 0e0ce33..0000000 --- a/SOURCES/0024-Update-translations-RHEL-8.7.patch +++ /dev/null @@ -1,2637 +0,0 @@ -From 147460b9e9cc33e03c77c03aa77c9eab15c535b4 Mon Sep 17 00:00:00 2001 -From: Marek Blaha -Date: Wed, 14 Sep 2022 13:20:38 +0200 -Subject: [PATCH] Update translations RHEL 8.7 - ---- - po/dnf-plugins-core.pot | 163 ++++++++++++------- - po/fr.po | 186 ++++++++++++++-------- - po/ja.po | 219 ++++++++++++++++---------- - po/ko.po | 341 +++++++++++++++++++++++----------------- - po/zh_CN.po | 194 ++++++++++++++--------- - 5 files changed, 687 insertions(+), 416 deletions(-) - -diff --git a/po/dnf-plugins-core.pot b/po/dnf-plugins-core.pot -index 3ec9a50..735a54d 100644 ---- a/po/dnf-plugins-core.pot -+++ b/po/dnf-plugins-core.pot -@@ -8,7 +8,7 @@ msgid "" - msgstr "" - "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" --"POT-Creation-Date: 2022-02-28 11:53+0100\n" -+"POT-Creation-Date: 2022-08-30 15:38+0200\n" - "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" - "Last-Translator: FULL NAME \n" - "Language-Team: LANGUAGE \n" -@@ -201,27 +201,27 @@ msgstr[1] "" - msgid "Could not save repo to repofile %s: %s" - msgstr "" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "y" - msgstr "" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "yes" - msgstr "" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "n" - msgstr "" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "no" - msgstr "" - --#: plugins/copr.py:84 -+#: plugins/copr.py:92 - msgid "Interact with Copr repositories." - msgstr "" - --#: plugins/copr.py:86 -+#: plugins/copr.py:94 - msgid "" - "\n" - " enable name/project [chroot]\n" -@@ -242,63 +242,63 @@ msgid "" - " " - msgstr "" - --#: plugins/copr.py:112 -+#: plugins/copr.py:120 - msgid "List all installed Copr repositories (default)" - msgstr "" - --#: plugins/copr.py:114 -+#: plugins/copr.py:122 - msgid "List enabled Copr repositories" - msgstr "" - --#: plugins/copr.py:116 -+#: plugins/copr.py:124 - msgid "List disabled Copr repositories" - msgstr "" - --#: plugins/copr.py:118 -+#: plugins/copr.py:126 - msgid "List available Copr repositories by user NAME" - msgstr "" - --#: plugins/copr.py:120 -+#: plugins/copr.py:128 - msgid "Specify an instance of Copr to work with" - msgstr "" - --#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 -+#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 - msgid "Error: " - msgstr "" - --#: plugins/copr.py:155 -+#: plugins/copr.py:165 - msgid "" - "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" - "copr_projectname` format" - msgstr "" - --#: plugins/copr.py:158 -+#: plugins/copr.py:168 - msgid "multiple hubs specified" - msgstr "" - --#: plugins/copr.py:223 plugins/copr.py:227 -+#: plugins/copr.py:237 plugins/copr.py:241 - msgid "exactly two additional parameters to copr command are required" - msgstr "" - --#: plugins/copr.py:232 -+#: plugins/copr.py:246 - msgid "Too many arguments." - msgstr "" - --#: plugins/copr.py:235 -+#: plugins/copr.py:249 - msgid "" - "Bad format of optional chroot. The format is distribution-version-" - "architecture." - msgstr "" - --#: plugins/copr.py:250 -+#: plugins/copr.py:264 - msgid "use format `copr_username/copr_projectname` to reference copr project" - msgstr "" - --#: plugins/copr.py:252 -+#: plugins/copr.py:266 - msgid "bad copr project format" - msgstr "" - --#: plugins/copr.py:266 -+#: plugins/copr.py:280 - msgid "" - "\n" - "Enabling a Copr repository. Please note that this repository is not part\n" -@@ -314,71 +314,102 @@ msgid "" - "Bugzilla. In case of problems, contact the owner of this repository.\n" - msgstr "" - --#: plugins/copr.py:283 -+#: plugins/copr.py:297 - msgid "Repository successfully enabled." - msgstr "" - --#: plugins/copr.py:288 -+#: plugins/copr.py:302 - msgid "Repository successfully disabled." - msgstr "" - --#: plugins/copr.py:292 -+#: plugins/copr.py:306 - msgid "Repository successfully removed." - msgstr "" - --#: plugins/copr.py:296 plugins/copr.py:697 -+#: plugins/copr.py:310 plugins/copr.py:721 - msgid "Unknown subcommand {}." - msgstr "" - --#: plugins/copr.py:353 -+#: plugins/copr.py:367 - msgid "" - "* These coprs have repo file with an old format that contains no information " - "about Copr hub - the default one was assumed. Re-enable the project to fix " - "this." - msgstr "" - --#: plugins/copr.py:366 -+#: plugins/copr.py:380 - msgid "Can't parse repositories for username '{}'." - msgstr "" - --#: plugins/copr.py:369 -+#: plugins/copr.py:383 - msgid "List of {} coprs" - msgstr "" - --#: plugins/copr.py:374 -+#: plugins/copr.py:388 - msgid "No description given" - msgstr "" - --#: plugins/copr.py:386 -+#: plugins/copr.py:400 - msgid "Can't parse search for '{}'." - msgstr "" - --#: plugins/copr.py:389 -+#: plugins/copr.py:403 - msgid "Matched: {}" - msgstr "" - --#: plugins/copr.py:394 -+#: plugins/copr.py:408 - msgid "No description given." - msgstr "" - --#: plugins/copr.py:416 -+#: plugins/copr.py:430 - msgid "Safe and good answer. Exiting." - msgstr "" - --#: plugins/copr.py:423 -+#: plugins/copr.py:437 - msgid "This command has to be run under the root user." - msgstr "" - --#: plugins/copr.py:485 -+#: plugins/copr.py:487 -+#, python-brace-format -+msgid "Request to {0} failed: {1} - {2}" -+msgstr "" -+ -+#: plugins/copr.py:489 -+msgid "It wasn't possible to enable this project.\n" -+msgstr "" -+ -+#: plugins/copr.py:494 -+#, python-brace-format -+msgid "Repository '{0}' does not exist in project '{1}'." -+msgstr "" -+ -+#: plugins/copr.py:497 - msgid "" --"This repository does not have any builds yet so you cannot enable it now." -+"\n" -+"Available repositories: " - msgstr "" - --#: plugins/copr.py:488 --msgid "Such repository does not exist." -+#: plugins/copr.py:499 -+#, python-brace-format -+msgid "" -+"\n" -+"\n" -+"If you want to enable a non-default repository, use the following command:\n" -+" 'dnf copr enable {0} '\n" -+"But note that the installed repo file will likely need a manual modification." -+msgstr "" -+ -+#: plugins/copr.py:505 -+#, python-brace-format -+msgid "Project {0} does not exist." -+msgstr "" -+ -+#: plugins/copr.py:508 -+#, python-brace-format -+msgid "Failed to connect to {0}: {1}" - msgstr "" - --#: plugins/copr.py:532 -+#: plugins/copr.py:555 - #, python-brace-format - msgid "" - "Maintainer of the enabled Copr repository decided to make\n" -@@ -395,44 +426,44 @@ msgid "" - "These repositories have been enabled automatically." - msgstr "" - --#: plugins/copr.py:553 -+#: plugins/copr.py:576 - msgid "Do you want to keep them enabled?" - msgstr "" - --#: plugins/copr.py:586 -+#: plugins/copr.py:609 - #, python-brace-format - msgid "Failed to remove copr repo {0}/{1}/{2}" - msgstr "" - --#: plugins/copr.py:597 -+#: plugins/copr.py:620 - msgid "Failed to disable copr repo {}/{}" - msgstr "" - --#: plugins/copr.py:615 plugins/copr.py:652 -+#: plugins/copr.py:638 plugins/copr.py:675 - msgid "Unknown response from server." - msgstr "" - --#: plugins/copr.py:637 -+#: plugins/copr.py:660 - msgid "Interact with Playground repository." - msgstr "" - --#: plugins/copr.py:643 -+#: plugins/copr.py:666 - msgid "Enabling a Playground repository." - msgstr "" - --#: plugins/copr.py:644 -+#: plugins/copr.py:667 - msgid "Do you want to continue?" - msgstr "" - --#: plugins/copr.py:687 -+#: plugins/copr.py:711 - msgid "Playground repositories successfully enabled." - msgstr "" - --#: plugins/copr.py:690 -+#: plugins/copr.py:714 - msgid "Playground repositories successfully disabled." - msgstr "" - --#: plugins/copr.py:694 -+#: plugins/copr.py:718 - msgid "Playground repositories successfully updated." - msgstr "" - -@@ -845,18 +876,18 @@ msgid "Bad Action Line \"%s\": %s" - msgstr "" - - #. unsupported state, skip it --#: plugins/post-transaction-actions.py:130 -+#: plugins/post-transaction-actions.py:133 - #, python-format - msgid "Bad Transaction State: %s" - msgstr "" - --#: plugins/post-transaction-actions.py:157 --#: plugins/post-transaction-actions.py:159 -+#: plugins/post-transaction-actions.py:160 -+#: plugins/post-transaction-actions.py:162 - #, python-format - msgid "post-transaction-actions: %s" - msgstr "" - --#: plugins/post-transaction-actions.py:161 -+#: plugins/post-transaction-actions.py:164 - #, python-format - msgid "post-transaction-actions: Bad Command \"%s\": %s" - msgstr "" -@@ -1027,31 +1058,43 @@ msgstr "" - msgid "Pass either --old or --new, not both!" - msgstr "" - --#: plugins/repomanage.py:89 -+#: plugins/repomanage.py:61 -+msgid "Pass either --oldonly or --new, not both!" -+msgstr "" -+ -+#: plugins/repomanage.py:63 -+msgid "Pass either --old or --oldonly, not both!" -+msgstr "" -+ -+#: plugins/repomanage.py:100 - msgid "No files to process" - msgstr "" - --#: plugins/repomanage.py:96 -+#: plugins/repomanage.py:107 - msgid "Could not open {}" - msgstr "" - --#: plugins/repomanage.py:180 -+#: plugins/repomanage.py:223 - msgid "Print the older packages" - msgstr "" - --#: plugins/repomanage.py:182 -+#: plugins/repomanage.py:225 -+msgid "Print the older packages. Exclude the newest packages." -+msgstr "" -+ -+#: plugins/repomanage.py:227 - msgid "Print the newest packages" - msgstr "" - --#: plugins/repomanage.py:184 -+#: plugins/repomanage.py:229 - msgid "Space separated output, not newline" - msgstr "" - --#: plugins/repomanage.py:186 -+#: plugins/repomanage.py:231 - msgid "Newest N packages to keep - defaults to 1" - msgstr "" - --#: plugins/repomanage.py:189 -+#: plugins/repomanage.py:234 - msgid "Path to directory" - msgstr "" - -diff --git a/po/fr.po b/po/fr.po -index f70bfb2..53ed3fb 100644 ---- a/po/fr.po -+++ b/po/fr.po -@@ -12,11 +12,11 @@ msgid "" - msgstr "" - "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" --"POT-Creation-Date: 2022-02-28 11:53+0100\n" -+"POT-Creation-Date: 2022-08-30 15:38+0200\n" - "PO-Revision-Date: 2022-03-09 12:39+0000\n" - "Last-Translator: Ludek Janda \n" --"Language-Team: French \n" -+"Language-Team: French \n" - "Language: fr\n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" -@@ -219,27 +219,27 @@ msgstr[1] "La configuration des dépôts a échoué" - msgid "Could not save repo to repofile %s: %s" - msgstr "Sauvegarde impossible du dépôt dans le fichier du dépôt %s : %s" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "y" - msgstr "o" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "yes" - msgstr "oui" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "n" - msgstr "n" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "no" - msgstr "non" - --#: plugins/copr.py:84 -+#: plugins/copr.py:92 - msgid "Interact with Copr repositories." - msgstr "Interagit avec les dépôts Copr." - --#: plugins/copr.py:86 -+#: plugins/copr.py:94 - msgid "" - "\n" - " enable name/project [chroot]\n" -@@ -277,31 +277,31 @@ msgstr "" - " copr search tests\n" - " " - --#: plugins/copr.py:112 -+#: plugins/copr.py:120 - msgid "List all installed Copr repositories (default)" - msgstr "Lister tous les dépôts Copr installés (par défaut)" - --#: plugins/copr.py:114 -+#: plugins/copr.py:122 - msgid "List enabled Copr repositories" - msgstr "Lister les dépôts Copr activés" - --#: plugins/copr.py:116 -+#: plugins/copr.py:124 - msgid "List disabled Copr repositories" - msgstr "Lister les dépôts Copr désactivés" - --#: plugins/copr.py:118 -+#: plugins/copr.py:126 - msgid "List available Copr repositories by user NAME" - msgstr "Lister les dépôts Copr disponibles par NOM d’utilisateur" - --#: plugins/copr.py:120 -+#: plugins/copr.py:128 - msgid "Specify an instance of Copr to work with" - msgstr "Précisez une instance Copr avec laquelle travailler" - --#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 -+#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 - msgid "Error: " - msgstr "Erreur : " - --#: plugins/copr.py:155 -+#: plugins/copr.py:165 - msgid "" - "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" - "copr_projectname` format" -@@ -309,19 +309,19 @@ msgstr "" - "précisez un hub Copr soit via `--hub` ou en utilisant le format `hub_copr/" - "utilisateur_copr/projet_copr`" - --#: plugins/copr.py:158 -+#: plugins/copr.py:168 - msgid "multiple hubs specified" - msgstr "de multiples hubs ont été renseignés" - --#: plugins/copr.py:223 plugins/copr.py:227 -+#: plugins/copr.py:237 plugins/copr.py:241 - msgid "exactly two additional parameters to copr command are required" - msgstr "la commande copr requiert exactement deux paramètres additionnels" - --#: plugins/copr.py:232 -+#: plugins/copr.py:246 - msgid "Too many arguments." - msgstr "Trop d'arguments." - --#: plugins/copr.py:235 -+#: plugins/copr.py:249 - msgid "" - "Bad format of optional chroot. The format is distribution-version-" - "architecture." -@@ -329,17 +329,17 @@ msgstr "" - "Mauvais format du chroot optionnel. Le format est distribution-version-" - "architecture." - --#: plugins/copr.py:250 -+#: plugins/copr.py:264 - msgid "use format `copr_username/copr_projectname` to reference copr project" - msgstr "" - "utilisez le format `copr_username/copr_projectname` pour faire référence au " - "projet copr" - --#: plugins/copr.py:252 -+#: plugins/copr.py:266 - msgid "bad copr project format" - msgstr "mauvais format de projet copr" - --#: plugins/copr.py:266 -+#: plugins/copr.py:280 - msgid "" - "\n" - "Enabling a Copr repository. Please note that this repository is not part\n" -@@ -368,23 +368,23 @@ msgstr "" - "de Fedora.\n" - "En cas de problèmes, contactez le propriétaire de ce dépôt.\n" - --#: plugins/copr.py:283 -+#: plugins/copr.py:297 - msgid "Repository successfully enabled." - msgstr "Activation du dépôt réussie." - --#: plugins/copr.py:288 -+#: plugins/copr.py:302 - msgid "Repository successfully disabled." - msgstr "Désactivation du dépôt réussie." - --#: plugins/copr.py:292 -+#: plugins/copr.py:306 - msgid "Repository successfully removed." - msgstr "Suppression du dépôt réussie." - --#: plugins/copr.py:296 plugins/copr.py:697 -+#: plugins/copr.py:310 plugins/copr.py:721 - msgid "Unknown subcommand {}." - msgstr "Sous-commande inconnue {}." - --#: plugins/copr.py:353 -+#: plugins/copr.py:367 - msgid "" - "* These coprs have repo file with an old format that contains no information " - "about Copr hub - the default one was assumed. Re-enable the project to fix " -@@ -394,51 +394,85 @@ msgstr "" - "aucune information à propos de Copr hub - celui par défaut a été utilisé. " - "Réactivez le projet pour résoudre le problème." - --#: plugins/copr.py:366 -+#: plugins/copr.py:380 - msgid "Can't parse repositories for username '{}'." - msgstr "" - "Ne peut analyser les dépôts pour y chercher le nom d’utilisateur « {} »." - --#: plugins/copr.py:369 -+#: plugins/copr.py:383 - msgid "List of {} coprs" - msgstr "Liste de {} coprs" - --#: plugins/copr.py:374 -+#: plugins/copr.py:388 - msgid "No description given" - msgstr "Aucune description fournie" - --#: plugins/copr.py:386 -+#: plugins/copr.py:400 - msgid "Can't parse search for '{}'." - msgstr "Impossible d’analyser la recherche pour « {} »." - --#: plugins/copr.py:389 -+#: plugins/copr.py:403 - msgid "Matched: {}" - msgstr "Correspondance : {}" - --#: plugins/copr.py:394 -+#: plugins/copr.py:408 - msgid "No description given." - msgstr "Pas de description fournie." - --#: plugins/copr.py:416 -+#: plugins/copr.py:430 - msgid "Safe and good answer. Exiting." - msgstr "Réponse sûre et exacte. Fin." - --#: plugins/copr.py:423 -+#: plugins/copr.py:437 - msgid "This command has to be run under the root user." - msgstr "Cette commande requiert les privilèges du super utilisateur." - --#: plugins/copr.py:485 -+#: plugins/copr.py:487 -+#, python-brace-format -+msgid "Request to {0} failed: {1} - {2}" -+msgstr "" -+ -+#: plugins/copr.py:489 -+msgid "It wasn't possible to enable this project.\n" -+msgstr "" -+ -+#: plugins/copr.py:494 -+#, fuzzy, python-brace-format -+#| msgid "Such repository does not exist." -+msgid "Repository '{0}' does not exist in project '{1}'." -+msgstr "Ce dépôt n’existe pas." -+ -+#: plugins/copr.py:497 -+#, fuzzy -+#| msgid "List enabled Copr repositories" - msgid "" --"This repository does not have any builds yet so you cannot enable it now." -+"\n" -+"Available repositories: " -+msgstr "Lister les dépôts Copr activés" -+ -+#: plugins/copr.py:499 -+#, python-brace-format -+msgid "" -+"\n" -+"\n" -+"If you want to enable a non-default repository, use the following command:\n" -+" 'dnf copr enable {0} '\n" -+"But note that the installed repo file will likely need a manual modification." - msgstr "" --"Ce dépôt ne contient pas encore d’exécutables vous ne pouvez donc pas " --"l’activer." - --#: plugins/copr.py:488 --msgid "Such repository does not exist." -+#: plugins/copr.py:505 -+#, fuzzy, python-brace-format -+#| msgid "Such repository does not exist." -+msgid "Project {0} does not exist." - msgstr "Ce dépôt n’existe pas." - --#: plugins/copr.py:532 -+#: plugins/copr.py:508 -+#, fuzzy, python-brace-format -+#| msgid "Failed to remove copr repo {0}/{1}/{2}" -+msgid "Failed to connect to {0}: {1}" -+msgstr "Échec de la suppression du dépôt Copr {0}/{1}/{2}" -+ -+#: plugins/copr.py:555 - #, python-brace-format - msgid "" - "Maintainer of the enabled Copr repository decided to make\n" -@@ -467,44 +501,44 @@ msgstr "" - "\n" - "Ces dépôts ont été activés automatiquement." - --#: plugins/copr.py:553 -+#: plugins/copr.py:576 - msgid "Do you want to keep them enabled?" - msgstr "Souhaitez-vous les maintenir activés ?" - --#: plugins/copr.py:586 -+#: plugins/copr.py:609 - #, python-brace-format - msgid "Failed to remove copr repo {0}/{1}/{2}" - msgstr "Échec de la suppression du dépôt Copr {0}/{1}/{2}" - --#: plugins/copr.py:597 -+#: plugins/copr.py:620 - msgid "Failed to disable copr repo {}/{}" - msgstr "Échec de la désactivation du dépôt copr {}/{}" - --#: plugins/copr.py:615 plugins/copr.py:652 -+#: plugins/copr.py:638 plugins/copr.py:675 - msgid "Unknown response from server." - msgstr "Réponse inconnue du serveur." - --#: plugins/copr.py:637 -+#: plugins/copr.py:660 - msgid "Interact with Playground repository." - msgstr "Interagit avec le dépôt Playground." - --#: plugins/copr.py:643 -+#: plugins/copr.py:666 - msgid "Enabling a Playground repository." - msgstr "Activation d’un dépôt Playground." - --#: plugins/copr.py:644 -+#: plugins/copr.py:667 - msgid "Do you want to continue?" - msgstr "Souhaitez-vous continuer ?" - --#: plugins/copr.py:687 -+#: plugins/copr.py:711 - msgid "Playground repositories successfully enabled." - msgstr "Activation des dépôts Playground réussie." - --#: plugins/copr.py:690 -+#: plugins/copr.py:714 - msgid "Playground repositories successfully disabled." - msgstr "Désactivation des dépôts Playground réussie." - --#: plugins/copr.py:694 -+#: plugins/copr.py:718 - msgid "Playground repositories successfully updated." - msgstr "Mise à jour des dépôts Playground réussie." - -@@ -954,18 +988,18 @@ msgid "Bad Action Line \"%s\": %s" - msgstr "Mauvaise ligne d’action « %s » : %s" - - #. unsupported state, skip it --#: plugins/post-transaction-actions.py:130 -+#: plugins/post-transaction-actions.py:133 - #, python-format - msgid "Bad Transaction State: %s" - msgstr "Mauvais état de transaction : %s" - --#: plugins/post-transaction-actions.py:157 --#: plugins/post-transaction-actions.py:159 -+#: plugins/post-transaction-actions.py:160 -+#: plugins/post-transaction-actions.py:162 - #, python-format - msgid "post-transaction-actions: %s" - msgstr "post-transaction-actions : %s" - --#: plugins/post-transaction-actions.py:161 -+#: plugins/post-transaction-actions.py:164 - #, python-format - msgid "post-transaction-actions: Bad Command \"%s\": %s" - msgstr "post-transaction-actions : mauvaise commande « %s » : %s" -@@ -1152,31 +1186,49 @@ msgstr "Gère un dossier de paquets rpm" - msgid "Pass either --old or --new, not both!" - msgstr "Passez soit --old, soit --new, mais pas les deux !" - --#: plugins/repomanage.py:89 -+#: plugins/repomanage.py:61 -+#, fuzzy -+#| msgid "Pass either --old or --new, not both!" -+msgid "Pass either --oldonly or --new, not both!" -+msgstr "Passez soit --old, soit --new, mais pas les deux !" -+ -+#: plugins/repomanage.py:63 -+#, fuzzy -+#| msgid "Pass either --old or --new, not both!" -+msgid "Pass either --old or --oldonly, not both!" -+msgstr "Passez soit --old, soit --new, mais pas les deux !" -+ -+#: plugins/repomanage.py:100 - msgid "No files to process" - msgstr "Aucun fichier à traiter" - --#: plugins/repomanage.py:96 -+#: plugins/repomanage.py:107 - msgid "Could not open {}" - msgstr "Ouverture de {} impossible" - --#: plugins/repomanage.py:180 -+#: plugins/repomanage.py:223 - msgid "Print the older packages" - msgstr "Afficher les paquets plus anciens" - --#: plugins/repomanage.py:182 -+#: plugins/repomanage.py:225 -+#, fuzzy -+#| msgid "Print the newest packages" -+msgid "Print the older packages. Exclude the newest packages." -+msgstr "Afficher les paquets les plus récents" -+ -+#: plugins/repomanage.py:227 - msgid "Print the newest packages" - msgstr "Afficher les paquets les plus récents" - --#: plugins/repomanage.py:184 -+#: plugins/repomanage.py:229 - msgid "Space separated output, not newline" - msgstr "Sorties séparées par des espaces plutôt que des retours à la ligne" - --#: plugins/repomanage.py:186 -+#: plugins/repomanage.py:231 - msgid "Newest N packages to keep - defaults to 1" - msgstr "N paquets les plus récents à conserver — par défaut 1" - --#: plugins/repomanage.py:189 -+#: plugins/repomanage.py:234 - msgid "Path to directory" - msgstr "Chemin vers le répertoire" - -@@ -1361,6 +1413,12 @@ msgstr "" - "La sous-commande '{}' est obsolète. Utilisez plutôt la sous-commande " - "'exclude'." - -+#~ msgid "" -+#~ "This repository does not have any builds yet so you cannot enable it now." -+#~ msgstr "" -+#~ "Ce dépôt ne contient pas encore d’exécutables vous ne pouvez donc pas " -+#~ "l’activer." -+ - #~ msgid "" - #~ "\n" - #~ "These repositories have been enabled automatically.\n" -diff --git a/po/ja.po b/po/ja.po -index c5c4691..7f9952d 100644 ---- a/po/ja.po -+++ b/po/ja.po -@@ -7,8 +7,8 @@ msgid "" - msgstr "" - "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" --"POT-Creation-Date: 2022-02-28 11:53+0100\n" --"PO-Revision-Date: 2022-03-09 12:39+0000\n" -+"POT-Creation-Date: 2022-08-30 15:38+0200\n" -+"PO-Revision-Date: 2022-09-07 14:19+0000\n" - "Last-Translator: Transtats \n" - "Language-Team: Japanese \n" -@@ -17,7 +17,7 @@ msgstr "" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=1; plural=0;\n" --"X-Generator: Weblate 4.11.2\n" -+"X-Generator: Weblate 4.14\n" - - #: plugins/builddep.py:45 - msgid "[PACKAGE|PACKAGE.spec]" -@@ -209,27 +209,27 @@ msgstr[0] "repo の設定に失敗しました" - msgid "Could not save repo to repofile %s: %s" - msgstr "repofile %s に repo を保存できませんでした: %s" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "y" - msgstr "y" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "yes" - msgstr "はい" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "n" - msgstr "n" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "no" - msgstr "いいえ" - --#: plugins/copr.py:84 -+#: plugins/copr.py:92 - msgid "Interact with Copr repositories." - msgstr "Copr リポジトリーとの対話。" - --#: plugins/copr.py:86 -+#: plugins/copr.py:94 - msgid "" - "\n" - " enable name/project [chroot]\n" -@@ -267,32 +267,32 @@ msgstr "" - " copr search tests\n" - " " - --#: plugins/copr.py:112 -+#: plugins/copr.py:120 - msgid "List all installed Copr repositories (default)" - msgstr "" - "インストール済みのすべての Copr リポジトリーを一覧表示します (デフォルト)" - --#: plugins/copr.py:114 -+#: plugins/copr.py:122 - msgid "List enabled Copr repositories" - msgstr "有効化された Copr リポジトリーを一覧表示します" - --#: plugins/copr.py:116 -+#: plugins/copr.py:124 - msgid "List disabled Copr repositories" - msgstr "無効化された Copr リポジトリーを一覧表示します" - --#: plugins/copr.py:118 -+#: plugins/copr.py:126 - msgid "List available Copr repositories by user NAME" - msgstr "利用可能な Copr リポジトリーをユーザー NAME ごとに一覧表示します" - --#: plugins/copr.py:120 -+#: plugins/copr.py:128 - msgid "Specify an instance of Copr to work with" - msgstr "作業する Copr のインスタンスを指定します" - --#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 -+#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 - msgid "Error: " - msgstr "エラー: " - --#: plugins/copr.py:155 -+#: plugins/copr.py:165 - msgid "" - "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" - "copr_projectname` format" -@@ -300,36 +300,37 @@ msgstr "" - "`--hub` または `copr_hub/copr_username/copr_projectname` フォーマットを使っ" - "て、Copr ハブを指定します" - --#: plugins/copr.py:158 -+#: plugins/copr.py:168 - msgid "multiple hubs specified" - msgstr "複数のハブが指定されています" - --#: plugins/copr.py:223 plugins/copr.py:227 -+#: plugins/copr.py:237 plugins/copr.py:241 - msgid "exactly two additional parameters to copr command are required" - msgstr "copr コマンドに厳密に 2 つの追加パラメーターが必要です" - --#: plugins/copr.py:232 -+#: plugins/copr.py:246 - msgid "Too many arguments." - msgstr "引数が多すぎます。" - --#: plugins/copr.py:235 -+#: plugins/copr.py:249 - msgid "" - "Bad format of optional chroot. The format is distribution-version-" - "architecture." --msgstr "オプションの chroot の形式が無効です。正しい形式は distribution-version-" -+msgstr "" -+"オプションの chroot の形式が無効です。正しい形式は distribution-version-" - "architecture です。" - --#: plugins/copr.py:250 -+#: plugins/copr.py:264 - msgid "use format `copr_username/copr_projectname` to reference copr project" - msgstr "" - "copr プロジェクトを参照するには `copr_username/copr_projectname` 形式を使用し" - "ます" - --#: plugins/copr.py:252 -+#: plugins/copr.py:266 - msgid "bad copr project format" - msgstr "不正な copr プロジェクト形式" - --#: plugins/copr.py:266 -+#: plugins/copr.py:280 - msgid "" - "\n" - "Enabling a Copr repository. Please note that this repository is not part\n" -@@ -358,23 +359,23 @@ msgstr "" - "Fedora Bugzilla でこれらのパッケージに関するバグ報告をしないでください。\n" - "問題が発生した場合は、このリポジトリーのオーナーに連絡してください。\n" - --#: plugins/copr.py:283 -+#: plugins/copr.py:297 - msgid "Repository successfully enabled." - msgstr "リポジトリが正常に有効化されました。" - --#: plugins/copr.py:288 -+#: plugins/copr.py:302 - msgid "Repository successfully disabled." - msgstr "リポジトリが正常に無効化されました。" - --#: plugins/copr.py:292 -+#: plugins/copr.py:306 - msgid "Repository successfully removed." - msgstr "リポジトリーが正常に削除されました。" - --#: plugins/copr.py:296 plugins/copr.py:697 -+#: plugins/copr.py:310 plugins/copr.py:721 - msgid "Unknown subcommand {}." - msgstr "不明なサブコマンド {}。" - --#: plugins/copr.py:353 -+#: plugins/copr.py:367 - msgid "" - "* These coprs have repo file with an old format that contains no information " - "about Copr hub - the default one was assumed. Re-enable the project to fix " -@@ -384,49 +385,87 @@ msgstr "" - "ファイルがあります。デフォルトは仮定です。これを修正するには、プロジェクトを" - "再度有効化してください。" - --#: plugins/copr.py:366 -+#: plugins/copr.py:380 - msgid "Can't parse repositories for username '{}'." - msgstr "ユーザー名 '{}' のリポジトリーを解析できません。" - --#: plugins/copr.py:369 -+#: plugins/copr.py:383 - msgid "List of {} coprs" - msgstr "{} coprs の一覧" - --#: plugins/copr.py:374 -+#: plugins/copr.py:388 - msgid "No description given" - msgstr "説明がありません" - --#: plugins/copr.py:386 -+#: plugins/copr.py:400 - msgid "Can't parse search for '{}'." - msgstr "'{}' の検索を解析できません。" - --#: plugins/copr.py:389 -+#: plugins/copr.py:403 - msgid "Matched: {}" - msgstr "一致: {}" - --#: plugins/copr.py:394 -+#: plugins/copr.py:408 - msgid "No description given." - msgstr "説明が与えられていません。" - --#: plugins/copr.py:416 -+#: plugins/copr.py:430 - msgid "Safe and good answer. Exiting." - msgstr "安全で優れた回答。終了中。" - --#: plugins/copr.py:423 -+#: plugins/copr.py:437 - msgid "This command has to be run under the root user." - msgstr "このコマンドは root ユーザーの下で実行する必要があります。" - --#: plugins/copr.py:485 -+#: plugins/copr.py:487 -+#, python-brace-format -+msgid "Request to {0} failed: {1} - {2}" -+msgstr "{0} へのリクエストに失敗しました: {1} - {2}" -+ -+#: plugins/copr.py:489 -+msgid "It wasn't possible to enable this project.\n" -+msgstr "このプロジェクトを有効にすることができませんでした。\n" -+ -+#: plugins/copr.py:494 -+#, python-brace-format -+msgid "Repository '{0}' does not exist in project '{1}'." -+msgstr "'{0}' リポジトリーはプロジェクト '{1}' に存在しません。" -+ -+#: plugins/copr.py:497 -+msgid "" -+"\n" -+"Available repositories: " -+msgstr "" -+"\n" -+"利用可能なリポジトリー: " -+ -+#: plugins/copr.py:499 -+#, python-brace-format - msgid "" --"This repository does not have any builds yet so you cannot enable it now." -+"\n" -+"\n" -+"If you want to enable a non-default repository, use the following command:\n" -+" 'dnf copr enable {0} '\n" -+"But note that the installed repo file will likely need a manual modification." - msgstr "" --"このリポジトリーにはまだビルドがありませんので、今すぐ有効化できません。" -+"\n" -+"\n" -+"デフォルト以外のリポジトリーを有効にする場合は、以下のコマンドを使用します:\n" -+" 'dnf copr enable {0} '\n" -+"ただし、インストールされているリポジトリーファイルを手動で変更する必要がある" -+"可能性があることに注意してください。" - --#: plugins/copr.py:488 --msgid "Such repository does not exist." --msgstr "そのようなリポジトリーは存在しません。" -+#: plugins/copr.py:505 -+#, python-brace-format -+msgid "Project {0} does not exist." -+msgstr "プロジェクト {0} は存在しません。" - --#: plugins/copr.py:532 -+#: plugins/copr.py:508 -+#, python-brace-format -+msgid "Failed to connect to {0}: {1}" -+msgstr "{0} への接続に失敗しました: {1}" -+ -+#: plugins/copr.py:555 - #, python-brace-format - msgid "" - "Maintainer of the enabled Copr repository decided to make\n" -@@ -444,8 +483,8 @@ msgid "" - msgstr "" - "有効化した Copr リポジトリーの管理者は\n" - "他のリポジトリーに依存するように決めました。\n" --"そのようなリポジトリーは通常、主な Corp " --"レジストリー(ランタイム依存関係を提供) から RPM を\n" -+"そのようなリポジトリーは通常、主な Corp レジストリー(ランタイム依存関係を提" -+"供) から RPM を\n" - "正常にインストールするために必要です。\n" - "\n" - "上記の品質とバグ報告についての注意点がここでも適用\n" -@@ -456,44 +495,44 @@ msgstr "" - "\n" - "これらのリポジトリーは自動的に有効になっています。" - --#: plugins/copr.py:553 -+#: plugins/copr.py:576 - msgid "Do you want to keep them enabled?" - msgstr "有効にしておきますか?" - --#: plugins/copr.py:586 -+#: plugins/copr.py:609 - #, python-brace-format - msgid "Failed to remove copr repo {0}/{1}/{2}" - msgstr "copr repo {0}/{1}/{2} の削除に失敗しました" - --#: plugins/copr.py:597 -+#: plugins/copr.py:620 - msgid "Failed to disable copr repo {}/{}" - msgstr "copr repo {}/{} の無効化に失敗しました" - --#: plugins/copr.py:615 plugins/copr.py:652 -+#: plugins/copr.py:638 plugins/copr.py:675 - msgid "Unknown response from server." - msgstr "サーバーからの不明な応答です。" - --#: plugins/copr.py:637 -+#: plugins/copr.py:660 - msgid "Interact with Playground repository." - msgstr "Playground リポジトリーとの対話。" - --#: plugins/copr.py:643 -+#: plugins/copr.py:666 - msgid "Enabling a Playground repository." - msgstr "Playgroundのリポジトリーの有効化。" - --#: plugins/copr.py:644 -+#: plugins/copr.py:667 - msgid "Do you want to continue?" - msgstr "続行しますか?" - --#: plugins/copr.py:687 -+#: plugins/copr.py:711 - msgid "Playground repositories successfully enabled." - msgstr "Playground リポジトリーが正常に有効化されました。" - --#: plugins/copr.py:690 -+#: plugins/copr.py:714 - msgid "Playground repositories successfully disabled." - msgstr "Playground リポジトリーが正常に無効化されました。" - --#: plugins/copr.py:694 -+#: plugins/copr.py:718 - msgid "Playground repositories successfully updated." - msgstr "Playground リポジトリーが正常に更新されました。" - -@@ -822,7 +861,8 @@ msgstr "履歴データを移行中..." - #: plugins/modulesync.py:37 - msgid "" - "Download packages from modules and/or create a repository with modular data" --msgstr "モジュールからパッケージをダウンロードしたり、モジュラーデータでリポジトリー" -+msgstr "" -+"モジュールからパッケージをダウンロードしたり、モジュラーデータでリポジトリー" - "を作成したりします" - - #: plugins/modulesync.py:44 -@@ -839,8 +879,9 @@ msgstr "ソースパッケージを含むリポジトリーを有効にします - - #: plugins/modulesync.py:49 - msgid "enable repositories with debug-info and debug-source packages" --msgstr "debug-info パッケージおよび debug-source " --"パッケージでリポジトリーを有効にします" -+msgstr "" -+"debug-info パッケージおよび debug-source パッケージでリポジトリーを有効にしま" -+"す" - - #: plugins/modulesync.py:53 - msgid "download only packages from newest modules" -@@ -855,8 +896,9 @@ msgstr[0] "引数に一致するものが見つかりませんでした: '{}'" - msgid "" - "Creation of repository failed with return code {}. All downloaded content " - "was kept on the system" --msgstr "リポジトリーの作成は戻りコード {} " --"で失敗しました。ダウンロードされたコンテンツはすべてシステムに保持されました" -+msgstr "" -+"リポジトリーの作成は戻りコード {} で失敗しました。ダウンロードされたコンテン" -+"ツはすべてシステムに保持されました" - - #: plugins/modulesync.py:144 - #, python-brace-format -@@ -866,8 +908,9 @@ msgstr "モジュール '{1}' のアーティファクト '{0}' に一致する - #: plugins/modulesync.py:162 - #, python-brace-format - msgid "No match for package name '{0}' in profile {1} from module {2}" --msgstr "モジュール {2} からのプロファイル {1} のパッケージ名 '{0}' " --"に一致するものはありません" -+msgstr "" -+"モジュール {2} からのプロファイル {1} のパッケージ名 '{0}' に一致するものはあ" -+"りません" - - #: plugins/modulesync.py:166 - msgid "No mach for argument '{}'" -@@ -884,8 +927,8 @@ msgid "" - "No installed package found for package name \"{pkg}\" specified in needs-" - "restarting file \"{file}\"." - msgstr "" --"needs-restarting ファイル \"{file}\" に指定されている \"{pkg}\" " --"というパッケージのインストール済みパッケージが見つかりません。" -+"needs-restarting ファイル \"{file}\" に指定されている \"{pkg}\" というパッ" -+"ケージのインストール済みパッケージが見つかりません。" - - #: plugins/needs_restarting.py:220 - msgid "determine updated binaries that need restarting" -@@ -932,18 +975,18 @@ msgid "Bad Action Line \"%s\": %s" - msgstr "不正なアクション行 \"%s\": %s" - - #. unsupported state, skip it --#: plugins/post-transaction-actions.py:130 -+#: plugins/post-transaction-actions.py:133 - #, python-format - msgid "Bad Transaction State: %s" - msgstr "不正なトランザクション状態: %s" - --#: plugins/post-transaction-actions.py:157 --#: plugins/post-transaction-actions.py:159 -+#: plugins/post-transaction-actions.py:160 -+#: plugins/post-transaction-actions.py:162 - #, python-format - msgid "post-transaction-actions: %s" - msgstr "post-transaction-actions: %s" - --#: plugins/post-transaction-actions.py:161 -+#: plugins/post-transaction-actions.py:164 - #, python-format - msgid "post-transaction-actions: Bad Command \"%s\": %s" - msgstr "post-transaction-actions: 不正なコマンド \"%s\": %s" -@@ -1126,33 +1169,45 @@ msgstr "rpm パッケージのディレクトリーを管理します" - - #: plugins/repomanage.py:59 - msgid "Pass either --old or --new, not both!" --msgstr "--old または --new のいずれかを渡します。両方ではありません。" -+msgstr "--old または --new のいずれかを渡します、両方ではありません!" -+ -+#: plugins/repomanage.py:61 -+msgid "Pass either --oldonly or --new, not both!" -+msgstr "--oldonly または --new のいずれかを渡します、両方ではありません!" - --#: plugins/repomanage.py:89 -+#: plugins/repomanage.py:63 -+msgid "Pass either --old or --oldonly, not both!" -+msgstr "--old または --oldonly のいずれかを渡します、両方ではありません!" -+ -+#: plugins/repomanage.py:100 - msgid "No files to process" - msgstr "処理するファイルはありません" - --#: plugins/repomanage.py:96 -+#: plugins/repomanage.py:107 - msgid "Could not open {}" - msgstr "{} を開くことができません" - --#: plugins/repomanage.py:180 -+#: plugins/repomanage.py:223 - msgid "Print the older packages" - msgstr "古いパッケージを印刷します" - --#: plugins/repomanage.py:182 -+#: plugins/repomanage.py:225 -+msgid "Print the older packages. Exclude the newest packages." -+msgstr "古いパッケージを出力します。最新のパッケージを除外します。" -+ -+#: plugins/repomanage.py:227 - msgid "Print the newest packages" - msgstr "最新のパッケージを印刷します" - --#: plugins/repomanage.py:184 -+#: plugins/repomanage.py:229 - msgid "Space separated output, not newline" - msgstr "スペースで区切られた出力で、改行ではありません" - --#: plugins/repomanage.py:186 -+#: plugins/repomanage.py:231 - msgid "Newest N packages to keep - defaults to 1" - msgstr "維持する最新の N パッケージ - デフォルトは 1 に設定されます" - --#: plugins/repomanage.py:189 -+#: plugins/repomanage.py:234 - msgid "Path to directory" - msgstr "ディレクトリーへのパス" - -@@ -1323,8 +1378,14 @@ msgstr "パッケージ仕様をそのまま使用し、解析を試みないで - - #: plugins/versionlock.py:160 - msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." --msgstr "サブコマンド '{}' は非推奨になりました。代わりに 'exclude' " --"サブコマンドを使用してください。" -+msgstr "" -+"サブコマンド '{}' は非推奨になりました。代わりに 'exclude' サブコマンドを使用" -+"してください。" -+ -+#~ msgid "" -+#~ "This repository does not have any builds yet so you cannot enable it now." -+#~ msgstr "" -+#~ "このリポジトリーにはまだビルドがありませんので、今すぐ有効化できません。" - - #~ msgid "" - #~ "\n" -diff --git a/po/ko.po b/po/ko.po -index 307ccc7..e2e3009 100644 ---- a/po/ko.po -+++ b/po/ko.po -@@ -1,13 +1,14 @@ - # Ludek Janda , 2018. #zanata, 2020. - # simmon , 2021. - # Kim InSoo , 2022. -+# 김인수 , 2022. - msgid "" - msgstr "" - "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" --"POT-Creation-Date: 2022-02-28 11:53+0100\n" --"PO-Revision-Date: 2022-03-02 04:16+0000\n" --"Last-Translator: Kim InSoo \n" -+"POT-Creation-Date: 2022-08-30 15:38+0200\n" -+"PO-Revision-Date: 2022-09-02 02:19+0000\n" -+"Last-Translator: 김인수 \n" - "Language-Team: Korean \n" - "Language: ko\n" -@@ -15,7 +16,7 @@ msgstr "" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=1; plural=0;\n" --"X-Generator: Weblate 4.11\n" -+"X-Generator: Weblate 4.14\n" - - #: plugins/builddep.py:45 - msgid "[PACKAGE|PACKAGE.spec]" -@@ -28,7 +29,7 @@ msgstr "'%s'는 'MACRO EXPR' 형식이 아닙니다" - - #: plugins/builddep.py:90 - msgid "packages with builddeps to install" --msgstr "설치 할 builddeps가 있는 꾸러미(package)" -+msgstr "설치 할 builddeps가 있는 꾸러미" - - #: plugins/builddep.py:93 - msgid "define a macro for spec file parsing" -@@ -44,7 +45,7 @@ msgstr "명령줄 인수를 지정한 파일로 다룬다" - - #: plugins/builddep.py:100 - msgid "treat commandline arguments as source rpm" --msgstr "명령줄 인수를 rpm 소스로 다룬다" -+msgstr "원천 rpm으로 명령줄 인수를 다룬다" - - #: plugins/builddep.py:144 - msgid "RPM: {}" -@@ -52,14 +53,14 @@ msgstr "RPM: {}" - - #: plugins/builddep.py:153 - msgid "Some packages could not be found." --msgstr "몇몇 꾸러미(packages)를 찾을 수 없습니다." -+msgstr "몇몇 꾸러미를 찾을 수 없습니다." - - #. No provides, no files - #. Richdeps can have no matches but it could be correct (solver must decide later) - #: plugins/builddep.py:173 - #, python-format - msgid "No matching package to install: '%s'" --msgstr "설치: '%s' 꾸러미(package)가 일치하지 않습니다" -+msgstr "설치: '%s' 꾸러미가 일치하지 않습니다" - - #: plugins/builddep.py:191 - #, python-format -@@ -78,16 +79,16 @@ msgstr "여는데 실패하였습니다 '%s', 지정한 파일: %s가 유효하 - #: plugins/builddep.py:230 plugins/repoclosure.py:118 - #, python-format - msgid "no package matched: %s" --msgstr "일치하는 꾸러미(package) 없음: %s" -+msgstr "일치하는 꾸러미 없음: %s" - - #: plugins/changelog.py:37 - #, python-brace-format - msgid "Not a valid date: \"{0}\"." --msgstr "유효한 날자가 아닙니다: \"{0}\"." -+msgstr "유효한 날짜가 아닙니다: \"{0}\"." - - #: plugins/changelog.py:43 - msgid "Show changelog data of packages" --msgstr "꾸러미(packages)의 변화 기록자료를 보여줍니다" -+msgstr "꾸러미의 변화 기록자료를 보여줍니다" - - #: plugins/changelog.py:51 - msgid "" -@@ -99,19 +100,19 @@ msgstr "" - - #: plugins/changelog.py:55 - msgid "show given number of changelog entries per package" --msgstr "주어진 수의 꾸러미(package) 마다 변화기록 항목을 보여줍니다" -+msgstr "주어진 수의 꾸러미 마다 변화기록 항목을 보여줍니다" - - #: plugins/changelog.py:58 - msgid "" - "show only new changelog entries for packages, that provide an upgrade for " - "some of already installed packages." - msgstr "" --"몇몇 이미 설치된 꾸러미(package)들의 최신화를 제공하는 꾸러미를 위하여 새로" --"운 변화기록만을 보여줍니다." -+"몇몇 이미 설치된 꾸러미들의 최신화를 제공하는 꾸러미를 위하여 새로운 변화기록" -+"만을 보여줍니다." - - #: plugins/changelog.py:60 - msgid "PACKAGE" --msgstr "꾸러미(package)" -+msgstr "꾸러미" - - #: plugins/changelog.py:81 plugins/debuginfo-install.py:90 - #, python-format -@@ -146,7 +147,7 @@ msgstr "{prog} 환경 선택과 저장소 관리" - - #: plugins/config_manager.py:45 - msgid "repo to modify" --msgstr "수정할 repo" -+msgstr "수정하려는 저장소" - - #: plugins/config_manager.py:48 - msgid "save the current options (useful with --setopt)" -@@ -204,27 +205,27 @@ msgstr[0] "저장소 구성에 실패했습니다" - msgid "Could not save repo to repofile %s: %s" - msgstr "repofile에 repo를 저장할 수 없습니다. %s: %s" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "y" - msgstr "y" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "yes" - msgstr "예" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "n" - msgstr "n" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "no" - msgstr "아니" - --#: plugins/copr.py:84 -+#: plugins/copr.py:92 - msgid "Interact with Copr repositories." - msgstr "Copr 저장소와 상호 작용하십시오." - --#: plugins/copr.py:86 -+#: plugins/copr.py:94 - msgid "" - "\n" - " enable name/project [chroot]\n" -@@ -262,31 +263,31 @@ msgstr "" - " copr search tests\n" - " " - --#: plugins/copr.py:112 -+#: plugins/copr.py:120 - msgid "List all installed Copr repositories (default)" - msgstr "설치된 모든 Copr 저장소 나열 (기본값)" - --#: plugins/copr.py:114 -+#: plugins/copr.py:122 - msgid "List enabled Copr repositories" - msgstr "사용 가능한 Copr 저장소 목록" - --#: plugins/copr.py:116 -+#: plugins/copr.py:124 - msgid "List disabled Copr repositories" - msgstr "비활성화 된 Copr 저장소 목록" - --#: plugins/copr.py:118 -+#: plugins/copr.py:126 - msgid "List available Copr repositories by user NAME" - msgstr "사용자가 사용할 수있는 Copr 저장소를 나열합니다. NAME" - --#: plugins/copr.py:120 -+#: plugins/copr.py:128 - msgid "Specify an instance of Copr to work with" - msgstr "일하는 Copr의 예를 지정합니다" - --#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 -+#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 - msgid "Error: " - msgstr "오류: " - --#: plugins/copr.py:155 -+#: plugins/copr.py:165 - msgid "" - "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" - "copr_projectname` format" -@@ -294,35 +295,35 @@ msgstr "" - "Corp hub를 `--hub` 또는 사용하기 `copr_hub/copr_username/copr_projectname`형" - "식으로 지정합니다" - --#: plugins/copr.py:158 -+#: plugins/copr.py:168 - msgid "multiple hubs specified" - msgstr "지정된 여러 허브" - --#: plugins/copr.py:223 plugins/copr.py:227 -+#: plugins/copr.py:237 plugins/copr.py:241 - msgid "exactly two additional parameters to copr command are required" - msgstr "copr 명령에 정확히 두 개의 추가 매개 변수가 필요합니다" - --#: plugins/copr.py:232 -+#: plugins/copr.py:246 - msgid "Too many arguments." - msgstr "너무 많은 인수." - --#: plugins/copr.py:235 -+#: plugins/copr.py:249 - msgid "" - "Bad format of optional chroot. The format is distribution-version-" - "architecture." - msgstr "선택적인 chroot의 나쁜 형식. 형식은 배포-버전-구조입니다." - --#: plugins/copr.py:250 -+#: plugins/copr.py:264 - msgid "use format `copr_username/copr_projectname` to reference copr project" - msgstr "" - "copr 프로젝트를 참조하기 위해`copr_username / copr_projectname` 형식을 사용하" - "십시오" - --#: plugins/copr.py:252 -+#: plugins/copr.py:266 - msgid "bad copr project format" - msgstr "나쁜 copr 프로젝트 형식" - --#: plugins/copr.py:266 -+#: plugins/copr.py:280 - msgid "" - "\n" - "Enabling a Copr repository. Please note that this repository is not part\n" -@@ -352,23 +353,23 @@ msgstr "" - "페도라 버그질라에 이들 꾸러미에 대한 파일 결점 보고를 제출하지 마세요.\n" - "이들 문제는, 이들 저장소 소유자와 접촉하세요.\n" - --#: plugins/copr.py:283 -+#: plugins/copr.py:297 - msgid "Repository successfully enabled." - msgstr "저장소가 사용 설정되었습니다." - --#: plugins/copr.py:288 -+#: plugins/copr.py:302 - msgid "Repository successfully disabled." - msgstr "저장소가 사용 중지되었습니다." - --#: plugins/copr.py:292 -+#: plugins/copr.py:306 - msgid "Repository successfully removed." - msgstr "저장소가 제거되었습니다." - --#: plugins/copr.py:296 plugins/copr.py:697 -+#: plugins/copr.py:310 plugins/copr.py:721 - msgid "Unknown subcommand {}." - msgstr "알 수없는 부속 명령 {}." - --#: plugins/copr.py:353 -+#: plugins/copr.py:367 - msgid "" - "* These coprs have repo file with an old format that contains no information " - "about Copr hub - the default one was assumed. Re-enable the project to fix " -@@ -377,48 +378,88 @@ msgstr "" - "* 이들 coprs은 Copr hub에 대하여 어떤 정보도 포함하지 않는 오래된 형태의 저장" - "소 파일을 갖고 있습니다. 이 문제를 수정하기 위하여 프로젝트를 재활성화하세요." - --#: plugins/copr.py:366 -+#: plugins/copr.py:380 - msgid "Can't parse repositories for username '{}'." - msgstr "사용자 이름 '{}'에 대한 리포지토리를 구문 분석 할 수 없습니다." - --#: plugins/copr.py:369 -+#: plugins/copr.py:383 - msgid "List of {} coprs" - msgstr "{} 명의 경찰 목록" - --#: plugins/copr.py:374 -+#: plugins/copr.py:388 - msgid "No description given" - msgstr "설명이 없습니다" - --#: plugins/copr.py:386 -+#: plugins/copr.py:400 - msgid "Can't parse search for '{}'." - msgstr "'{}'에 대한 검색을 구문 분석 할 수 없습니다." - --#: plugins/copr.py:389 -+#: plugins/copr.py:403 - msgid "Matched: {}" - msgstr "일치하는 항목 : {}" - --#: plugins/copr.py:394 -+#: plugins/copr.py:408 - msgid "No description given." - msgstr "설명이 없습니다." - --#: plugins/copr.py:416 -+#: plugins/copr.py:430 - msgid "Safe and good answer. Exiting." - msgstr "안전하고 좋은 대답. 나가기." - --#: plugins/copr.py:423 -+#: plugins/copr.py:437 - msgid "This command has to be run under the root user." - msgstr "이 명령은 루트 사용자로 실행해야합니다." - --#: plugins/copr.py:485 -+#: plugins/copr.py:487 -+#, python-brace-format -+msgid "Request to {0} failed: {1} - {2}" -+msgstr "{0}에 대한 요청이 실패함: {1} - {2}" -+ -+#: plugins/copr.py:489 -+msgid "It wasn't possible to enable this project.\n" -+msgstr "이와 같은 프로젝트를 활성화 할 수 없습니다.\n" -+ -+#: plugins/copr.py:494 -+#, python-brace-format -+msgid "Repository '{0}' does not exist in project '{1}'." -+msgstr "저장소 '{0}'는 프로젝트 '{1}'에 존재하지 않습니다." -+ -+#: plugins/copr.py:497 - msgid "" --"This repository does not have any builds yet so you cannot enable it now." --msgstr "이 저장소에는 빌드가 아직 없으므로 지금 사용할 수 없습니다." -+"\n" -+"Available repositories: " -+msgstr "" -+"\n" -+"사용 가능한 저장소: " -+ -+#: plugins/copr.py:499 -+#, python-brace-format -+msgid "" -+"\n" -+"\n" -+"If you want to enable a non-default repository, use the following command:\n" -+" 'dnf copr enable {0} '\n" -+"But note that the installed repo file will likely need a manual modification." -+msgstr "" -+"\n" -+"\n" -+"만약 기본설정되지 않은 저장소를 활성화 하고자 한다면, 다음 명령을 사용하세요:" -+" \n" -+" 'dnf copr enable {0} ' \n" -+"하지만 설치된 저장소 파일은 수동으로 수정해야 할 필요가 있다는 점을 " -+"참고하세요." - --#: plugins/copr.py:488 --msgid "Such repository does not exist." --msgstr "이러한 저장소는 존재하지 않습니다." -+#: plugins/copr.py:505 -+#, python-brace-format -+msgid "Project {0} does not exist." -+msgstr "프로젝트 {0}가 존재하지 않습니다." -+ -+#: plugins/copr.py:508 -+#, python-brace-format -+msgid "Failed to connect to {0}: {1}" -+msgstr "연결 하는데 실패함 {0}: {1}" - --#: plugins/copr.py:532 -+#: plugins/copr.py:555 - #, python-brace-format - msgid "" - "Maintainer of the enabled Copr repository decided to make\n" -@@ -447,50 +488,50 @@ msgstr "" - "\n" - "이들 저장소는 자동으로 활성화 됩니다." - --#: plugins/copr.py:553 -+#: plugins/copr.py:576 - msgid "Do you want to keep them enabled?" - msgstr "계속 사용하길 원하시나요?" - --#: plugins/copr.py:586 -+#: plugins/copr.py:609 - #, python-brace-format - msgid "Failed to remove copr repo {0}/{1}/{2}" - msgstr "copr repo {0}/{1}/{2} 제거를 실패하였습니다" - --#: plugins/copr.py:597 -+#: plugins/copr.py:620 - msgid "Failed to disable copr repo {}/{}" - msgstr "copr repo {} / {}를 사용 중지를 실패하였습니다" - --#: plugins/copr.py:615 plugins/copr.py:652 -+#: plugins/copr.py:638 plugins/copr.py:675 - msgid "Unknown response from server." - msgstr "서버에서 알 수없는 응답." - --#: plugins/copr.py:637 -+#: plugins/copr.py:660 - msgid "Interact with Playground repository." - msgstr "놀이터 저장소와 상호 작용하십시오." - --#: plugins/copr.py:643 -+#: plugins/copr.py:666 - msgid "Enabling a Playground repository." - msgstr "동작 저장소와 활용하기." - --#: plugins/copr.py:644 -+#: plugins/copr.py:667 - msgid "Do you want to continue?" - msgstr "계속하기를 원하십니까?" - --#: plugins/copr.py:687 -+#: plugins/copr.py:711 - msgid "Playground repositories successfully enabled." - msgstr "놀이터 저장소를 사용하도록 설정했습니다." - --#: plugins/copr.py:690 -+#: plugins/copr.py:714 - msgid "Playground repositories successfully disabled." - msgstr "놀이터 저장소가 사용 중지되었습니다." - --#: plugins/copr.py:694 -+#: plugins/copr.py:718 - msgid "Playground repositories successfully updated." - msgstr "놀이터 저장소가 성공적으로 업데이트되었습니다." - - #: plugins/debug.py:53 - msgid "dump information about installed rpm packages to file" --msgstr "설치된 rpm 꾸러미(package)에 대한 정보를 파일에 덤프하십시오" -+msgstr "설치된 rpm 꾸러미에 대한 정보를 파일에 덤프하세요" - - #: plugins/debug.py:67 - msgid "do not attempt to dump the repository contents." -@@ -507,7 +548,7 @@ msgstr "작성된 출력 : %s" - - #: plugins/debug.py:172 - msgid "restore packages recorded in debug-dump file" --msgstr "디버그 덤프 파일에 기록 된 꾸러미(package) 복원" -+msgstr "디버그 덤프 파일에 기록 된 꾸러미 복원" - - #: plugins/debug.py:185 - msgid "output commands that would be run to stdout." -@@ -544,7 +585,7 @@ msgstr "덤프 파일의 이름" - #: plugins/debug.py:273 - #, python-format - msgid "Package %s is not available" --msgstr "꾸러미(package) %s 사용 할 수 없습니다" -+msgstr "꾸러미 %s를 사용 할 수 없습니다" - - #: plugins/debug.py:283 - #, python-format -@@ -553,39 +594,32 @@ msgstr "잘못된 dnf 디버그 파일 : %s" - - #: plugins/debuginfo-install.py:56 - msgid "install debuginfo packages" --msgstr "디버그정보 꾸러미(package) 설치" -+msgstr "디버그정보 꾸러미 설치" - - #: plugins/debuginfo-install.py:180 - #, python-format - msgid "" - "Could not find debuginfo package for the following available packages: %s" - msgstr "" --"다음 사용가능한 꾸러미(package): %s 를 위하여 디버그정보 꾸러미를 찾을 수 없" --"습니다" -+"다음 사용가능한 꾸러미를 위하여 디버그정보 꾸러미를 찾을 수 없습니다: %s" - - #: plugins/debuginfo-install.py:185 - #, python-format - msgid "" - "Could not find debugsource package for the following available packages: %s" --msgstr "" --"다음 가용한 꾸러미(package): %s 를 위하여 디버그자원 꾸러미(package)를 찾을 " --"수 없습니다" -+msgstr "다음 가용한 꾸러미: %s 를 위하여 디버그자원 꾸러미를 찾을 수 없습니다" - - #: plugins/debuginfo-install.py:190 - #, python-format - msgid "" - "Could not find debuginfo package for the following installed packages: %s" --msgstr "" --"다음 설치된 꾸러미(package): %s 를 위한 디버그정보 꾸러미(package)를 찾을 수 " --"없습니다" -+msgstr "다음 설치된 꾸러미를 위한 디버그정보 꾸러미를 찾을 수 없습니다: %s" - - #: plugins/debuginfo-install.py:195 - #, python-format - msgid "" - "Could not find debugsource package for the following installed packages: %s" --msgstr "" --"다음 설치된 꾸러미(package): %s 를 위하여 디버그자원 꾸러미(package)를 찾을 " --"수 없습니다" -+msgstr "다음 설치된 꾸러미: %s 를 위하여 디버그자원 꾸러미를 찾을 수 없습니다" - - #: plugins/debuginfo-install.py:199 - msgid "Unable to find a match" -@@ -605,15 +639,15 @@ msgstr "대신 src.rpm을 내려받으세요" - - #: plugins/download.py:55 - msgid "download the -debuginfo package instead" --msgstr "대신 -debuginfo 꾸러미(package)를 내려받아요" -+msgstr "대신 -debuginfo 꾸러미를 내려받아요" - - #: plugins/download.py:57 - msgid "download the -debugsource package instead" --msgstr "대신 -debuginfo 꾸러미(package)를 내려받으세요" -+msgstr "대신 -debuginfo 꾸러미를 내려받으세요" - - #: plugins/download.py:60 - msgid "limit the query to packages of given architectures." --msgstr "요청를 주어진 구조 꾸러미(package)로 제한하십시오." -+msgstr "요청를 제공된 구조의 꾸러미로 제한합니다." - - #: plugins/download.py:62 plugins/modulesync.py:51 - msgid "resolve and download needed dependencies" -@@ -647,17 +681,17 @@ msgstr "엄격한 설정으로 인해 종료됩니다." - - #: plugins/download.py:261 - msgid "Error in resolve of packages:" --msgstr "꾸러미(package) 해결 오류 :" -+msgstr "꾸러미 해결 오류 :" - - #: plugins/download.py:279 - #, python-format - msgid "No source rpm defined for %s" --msgstr "소스 rpm이 정의되지 않았습니다. %s" -+msgstr "%s를 위한 원천 rpm이 정의되지 않음" - - #: plugins/download.py:296 plugins/download.py:309 - #, python-format - msgid "No package %s available." --msgstr "가용한 꾸러미(package) %s가 없습니다." -+msgstr "가용한 꾸러미 %s가 없습니다." - - #: plugins/groups_manager.py:49 - msgid "Invalid group id" -@@ -731,23 +765,23 @@ msgstr "그룹 사용자를 보이지 않게 표시" - - #: plugins/groups_manager.py:123 - msgid "add packages to the mandatory section" --msgstr "꾸러미(package)를 필 수 부분에 추가합니다" -+msgstr "꾸러미를 필수 부분에 추가합니다" - - #: plugins/groups_manager.py:125 - msgid "add packages to the optional section" --msgstr "꾸러미(package)를 선택 부분에 추가합니다" -+msgstr "꾸러미를 선택 부분에 추가합니다" - - #: plugins/groups_manager.py:127 - msgid "remove packages from the group instead of adding them" --msgstr "추가하기 대신에 그룹에서 꾸러미(package)를 제거합니다" -+msgstr "추가하기 대신에 그룹에서 꾸러미를 제거합니다" - - #: plugins/groups_manager.py:129 - msgid "include also direct dependencies for packages" --msgstr "꾸러미(package)를 위해 직접적인 의존성을 포함한다" -+msgstr "꾸러미를 위해 직접적인 의존성을 포함한다" - - #: plugins/groups_manager.py:132 - msgid "package specification" --msgstr "꾸러미(package) 사양" -+msgstr "꾸러미 사양" - - #: plugins/groups_manager.py:156 - msgid "Can't edit group without specifying it (use --id or --name)" -@@ -767,7 +801,7 @@ msgstr "일치하는 인수가 없습니다 :{}" - - #: plugins/groups_manager.py:298 - msgid "Can't remove packages from non-existent group" --msgstr "존재하지 않는 그룹에서 꾸러미(package)를 제거 할 수 없습니다" -+msgstr "존재하지 않는 그룹에서 꾸러미를 제거 할 수 없습니다" - - #: plugins/groups_manager.py:307 - msgid "" -@@ -779,7 +813,7 @@ msgstr "" - - #: plugins/leaves.py:32 - msgid "List installed packages not required by any other package" --msgstr "다른 꾸러미(package)에서 필요하지 않은 설치된 꾸러미(packages) 나열" -+msgstr "다른 꾸러미에서 필요하지 않은 설치된 꾸러미 나열" - - #: plugins/local.py:122 - msgid "Unable to create a directory '{}' due to '{}'" -@@ -812,23 +846,24 @@ msgstr "기록 데이터 마이그레이션 중 ..." - #: plugins/modulesync.py:37 - msgid "" - "Download packages from modules and/or create a repository with modular data" --msgstr "모듈에서 꾸러미를 내려 받기와/또는 모듈식 자료를 갖고 있는 저장소를 생성" -+msgstr "" -+"모듈에서 꾸러미를 내려 받기와/또는 모듈식 자료를 갖고 있는 저장소를 생성" - - #: plugins/modulesync.py:44 - msgid "MODULE" --msgstr "모듈" -+msgstr "MODULE" - - #: plugins/modulesync.py:45 - msgid "modules to download" --msgstr "내려받아야 할 모듈" -+msgstr "내려받기 할 모듈" - - #: plugins/modulesync.py:47 - msgid "enable repositories with source packages" --msgstr "원천 꾸러미와 함께 저장소를 활성화" -+msgstr "원천 꾸러미로 저장소 활성화" - - #: plugins/modulesync.py:49 - msgid "enable repositories with debug-info and debug-source packages" --msgstr "디버그-정보와 디버그-원천 꾸러미와 함께 저장소 활성화" -+msgstr "debug-info와 debug-source 꾸러미로 저장소 활성화" - - #: plugins/modulesync.py:53 - msgid "download only packages from newest modules" -@@ -837,28 +872,30 @@ msgstr "최신 모듈에서 꾸러미만 내려받기" - #: plugins/modulesync.py:85 - msgid "Unable to find a match for argument: '{}'" - msgid_plural "Unable to find a match for arguments: '{}'" --msgstr[0] "인수와 일치하는 항목을 찾을 수 없습니다: '{}'" -+msgstr[0] "인수와 일치 항목을 찾을 수 없음: '{}'" - - #: plugins/modulesync.py:107 - msgid "" - "Creation of repository failed with return code {}. All downloaded content " - "was kept on the system" --msgstr "반환 코드 {}로 인하여 저장소 생성에 실패함. 모두 내려받기된 내용은 " --"시스템에서 보관됩니다" -+msgstr "" -+"반환 코드 {}로 인하여 저장소 생성에 실패함. 모두 내려받기된 내용은 시스템에" -+"서 보관됩니다" - - #: plugins/modulesync.py:144 - #, python-brace-format - msgid "No match for artifact '{0}' from module '{1}'" --msgstr "모듈 '{1}'에서 인위 결과물 '{0}'과 일치하는 부분이 없습니다" -+msgstr "모듈 '{1}' 에서 인위 결과물 '{0}'과 일치하는 부분이 없습니다" - - #: plugins/modulesync.py:162 - #, python-brace-format - msgid "No match for package name '{0}' in profile {1} from module {2}" --msgstr "모듈 {2}에서 프로파일 {1}인 꾸러미 이름 '{0}'과 일치하는 부분이 없습니다" -+msgstr "" -+"모듈 {2}에서 프로파일 {1}인 꾸러미 이름 '{0}'과 일치하는 부분이 없습니다" - - #: plugins/modulesync.py:166 - msgid "No mach for argument '{}'" --msgstr "인수와 일치하는 항목이 없습니다 '{}'" -+msgstr "인수 '{}'와 일치하는 항목이 없습니다" - - #. TODO(jmracek) Shell we end with an error or with RC 1? - #: plugins/modulesync.py:198 -@@ -870,8 +907,9 @@ msgstr "필요사항 {}를 만족 할 수 없음" - msgid "" - "No installed package found for package name \"{pkg}\" specified in needs-" - "restarting file \"{file}\"." --msgstr "재시작이 필요한 파일 \"{file}\" 에 지정한 꾸러미 이름 \"{pkg}\"을 위하여 " --"설치된 꾸러미를 찾을 수 없습니다." -+msgstr "" -+"재시작이 필요한 파일 \"{file}\" 에 지정한 꾸러미 이름 \"{pkg}\"을 위하여 설치" -+"된 꾸러미를 찾을 수 없습니다." - - #: plugins/needs_restarting.py:220 - msgid "determine updated binaries that need restarting" -@@ -917,18 +955,18 @@ msgid "Bad Action Line \"%s\": %s" - msgstr "잘못된 동작 선 \"%s\": %s" - - #. unsupported state, skip it --#: plugins/post-transaction-actions.py:130 -+#: plugins/post-transaction-actions.py:133 - #, python-format - msgid "Bad Transaction State: %s" - msgstr "잘못된 연결 상태: %s" - --#: plugins/post-transaction-actions.py:157 --#: plugins/post-transaction-actions.py:159 -+#: plugins/post-transaction-actions.py:160 -+#: plugins/post-transaction-actions.py:162 - #, python-format - msgid "post-transaction-actions: %s" - msgstr "연결 후 동작: %s" - --#: plugins/post-transaction-actions.py:161 -+#: plugins/post-transaction-actions.py:164 - #, python-format - msgid "post-transaction-actions: Bad Command \"%s\": %s" - msgstr "연결 후 동작: 잘못된 명령 \"%s\": %s" -@@ -943,7 +981,7 @@ msgstr "재구 축은 해결되지 않은 종속성으로 종료되었습니다. - - #: plugins/repoclosure.py:153 - msgid "check packages of the given archs, can be specified multiple times" --msgstr "지정된 아치의 꾸러미(package)를 검사하고 여러 번 지정할 수 있습니다" -+msgstr "지정된 아치의 꾸러미를 검사하고 여러 번 지정할 수 있습니다" - - #: plugins/repoclosure.py:156 - msgid "Specify repositories to check" -@@ -951,11 +989,11 @@ msgstr "점검 할 저장소를 지정하세요" - - #: plugins/repoclosure.py:158 - msgid "Check only the newest packages in the repos" --msgstr "저장소 최신 꾸러미(package)만 확인하세요" -+msgstr "저장소 최신 꾸러미만 확인하세요" - - #: plugins/repoclosure.py:161 - msgid "Check closure for this package only" --msgstr "이 꾸러미(package)의 폐쇄만 확인하세요" -+msgstr "이 꾸러미의 폐쇄만 확인하세요" - - #: plugins/repodiff.py:45 - msgid "List differences between two sets of repositories" -@@ -985,12 +1023,12 @@ msgstr "크기 변화에 대한 추가 자료를 출력합니다." - msgid "" - "Compare packages also by arch. By default packages are compared just by name." - msgstr "" --"구조에 의해 꾸러미(package) 또한 비교합니다. 기본적으로 꾸러미(package)는 이" --"름으로만 비교됩니다." -+"구조에 의해 꾸러미 또한 비교합니다. 기본적으로 꾸러미는 이름으로만 비교됩니" -+"다." - - #: plugins/repodiff.py:72 - msgid "Output a simple one line message for modified packages." --msgstr "수정된 꾸러미(pacakage)지를 위해 단순히 한 줄 메시지를 출력합니다." -+msgstr "수정된 꾸러미를 위해 단순히 한 줄 메시지를 출력합니다." - - #: plugins/repodiff.py:74 - msgid "" -@@ -1008,11 +1046,11 @@ msgstr "크기 변화: {} bytes" - - #: plugins/repodiff.py:184 - msgid "Added package : {}" --msgstr "추가된 꾸러미(package) : {}" -+msgstr "추가된 꾸러미 : {}" - - #: plugins/repodiff.py:187 - msgid "Removed package: {}" --msgstr "제거된 꾸러미(package): {}" -+msgstr "제거된 꾸러미: {}" - - #: plugins/repodiff.py:190 - msgid "Obsoleted by : {}" -@@ -1024,7 +1062,7 @@ msgid "" - "Upgraded packages" - msgstr "" - "\n" --"향상된 꾸러미(package)" -+"향상된 꾸러미" - - #: plugins/repodiff.py:200 - msgid "" -@@ -1040,7 +1078,7 @@ msgid "" - "Modified packages" - msgstr "" - "\n" --"변형된 꾸러미(package)" -+"변형된 꾸러미" - - #: plugins/repodiff.py:212 - msgid "" -@@ -1052,35 +1090,35 @@ msgstr "" - - #: plugins/repodiff.py:213 - msgid "Added packages: {}" --msgstr "추가된 꾸러미(package): {}" -+msgstr "추가된 꾸러미: {}" - - #: plugins/repodiff.py:214 - msgid "Removed packages: {}" --msgstr "제거된 꾸러미(package): {}" -+msgstr "제거된 꾸러미: {}" - - #: plugins/repodiff.py:216 - msgid "Upgraded packages: {}" --msgstr "향상된 꾸러미(package): {}" -+msgstr "향상된 꾸러미: {}" - - #: plugins/repodiff.py:217 - msgid "Downgraded packages: {}" --msgstr "하향설치된 꾸러미: {}" -+msgstr "하향 설치된 꾸러미: {}" - - #: plugins/repodiff.py:219 - msgid "Modified packages: {}" --msgstr "변형된 꾸러미(package): {}" -+msgstr "변형된 꾸러미: {}" - - #: plugins/repodiff.py:222 - msgid "Size of added packages: {}" --msgstr "크기가 증가된 꾸러미(package): {}" -+msgstr "크기가 증가된 꾸러미: {}" - - #: plugins/repodiff.py:223 - msgid "Size of removed packages: {}" --msgstr "크기가 제거된 꾸러미(package): {}" -+msgstr "크기가 제거된 꾸러미: {}" - - #: plugins/repodiff.py:225 - msgid "Size of modified packages: {}" --msgstr "크기가 변형된 꾸러미(package): {}" -+msgstr "크기가 변형된 꾸러미: {}" - - #: plugins/repodiff.py:228 - msgid "Size of upgraded packages: {}" -@@ -1096,7 +1134,7 @@ msgstr "크기 변경: {}" - - #: plugins/repograph.py:50 - msgid "Output a full package dependency graph in dot format" --msgstr "도트 형식의 전체 꾸러미(package) 종속성 그래프 출력" -+msgstr "도트 형식의 전체 꾸러미 종속성 그래프 출력" - - #: plugins/repograph.py:110 - #, python-format -@@ -1105,43 +1143,55 @@ msgstr "아무것도 제공하지 않습니다 : '%s'" - - #: plugins/repomanage.py:45 - msgid "Manage a directory of rpm packages" --msgstr "rpm 꾸러미(package) 디렉토리 관리" -+msgstr "rpm 꾸러미 디렉토리 관리" - - #: plugins/repomanage.py:59 - msgid "Pass either --old or --new, not both!" - msgstr "--old 또는 --new 중 하나를 전달하세요!" - --#: plugins/repomanage.py:89 -+#: plugins/repomanage.py:61 -+msgid "Pass either --oldonly or --new, not both!" -+msgstr "--oldonly 또는 --new 중 하나를 전달하세요!" -+ -+#: plugins/repomanage.py:63 -+msgid "Pass either --old or --oldonly, not both!" -+msgstr "--oldonly 또는 --new 중 하나를 전달하세요!" -+ -+#: plugins/repomanage.py:100 - msgid "No files to process" - msgstr "처리 할 파일 없음" - --#: plugins/repomanage.py:96 -+#: plugins/repomanage.py:107 - msgid "Could not open {}" - msgstr "{}을 열 수 없습니다" - --#: plugins/repomanage.py:180 -+#: plugins/repomanage.py:223 - msgid "Print the older packages" --msgstr "이전 꾸러미(package) 인쇄" -+msgstr "이전 꾸러미 인쇄" - --#: plugins/repomanage.py:182 -+#: plugins/repomanage.py:225 -+msgid "Print the older packages. Exclude the newest packages." -+msgstr "오래된 꾸러미를 출력합니다. 최신 꾸러미는 제외합니다." -+ -+#: plugins/repomanage.py:227 - msgid "Print the newest packages" - msgstr "최신 꾸러미(package) 인쇄" - --#: plugins/repomanage.py:184 -+#: plugins/repomanage.py:229 - msgid "Space separated output, not newline" - msgstr "공백으로 구분 된 출력이 아닌 개행 문자" - --#: plugins/repomanage.py:186 -+#: plugins/repomanage.py:231 - msgid "Newest N packages to keep - defaults to 1" - msgstr "보관할 최신 N 꾸러미(package) - 기본값은 1입니다" - --#: plugins/repomanage.py:189 -+#: plugins/repomanage.py:234 - msgid "Path to directory" - msgstr "디렉토리 경로" - - #: plugins/reposync.py:55 - msgid "download all packages from remote repo" --msgstr "원격 저장소에서 모든 꾸러미(package)를 내려받아요" -+msgstr "원격 저장소에서 모든 꾸러미를 내려받아요" - - #: plugins/reposync.py:64 - msgid "download only packages for this ARCH" -@@ -1237,7 +1287,7 @@ msgstr "저장소에 대한 comps.xml %s 저장된" - - #: plugins/show_leaves.py:54 - msgid "New leaves:" --msgstr "독립 꾸러미(package):" -+msgstr "독립 꾸러미:" - - #: plugins/versionlock.py:33 - #, python-format -@@ -1303,8 +1353,13 @@ msgstr "꾸러미(package) 사양을 그대로 사용하며, 구문 분석을 - - #: plugins/versionlock.py:160 - msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." --msgstr "하위명령 '{}'는 더 이상 사용하지 않습니다. 대신에 하위명령 'exclude'를 " --"사용합니다." -+msgstr "" -+"하위명령 '{}'는 더 이상 사용하지 않습니다. 대신에 하위명령 'exclude'를 사용합" -+"니다." -+ -+#~ msgid "" -+#~ "This repository does not have any builds yet so you cannot enable it now." -+#~ msgstr "이 저장소에는 빌드가 아직 없으므로 지금 사용할 수 없습니다." - - #~ msgid "" - #~ "\n" -diff --git a/po/zh_CN.po b/po/zh_CN.po -index 5e5627e..37c1e9d 100644 ---- a/po/zh_CN.po -+++ b/po/zh_CN.po -@@ -12,8 +12,8 @@ msgid "" - msgstr "" - "Project-Id-Version: PACKAGE VERSION\n" - "Report-Msgid-Bugs-To: \n" --"POT-Creation-Date: 2022-02-28 11:53+0100\n" --"PO-Revision-Date: 2022-03-09 12:39+0000\n" -+"POT-Creation-Date: 2022-08-30 15:38+0200\n" -+"PO-Revision-Date: 2022-09-07 14:19+0000\n" - "Last-Translator: Transtats \n" - "Language-Team: Chinese (Simplified) \n" -@@ -22,7 +22,7 @@ msgstr "" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=1; plural=0;\n" --"X-Generator: Weblate 4.11.2\n" -+"X-Generator: Weblate 4.14\n" - - #: plugins/builddep.py:45 - msgid "[PACKAGE|PACKAGE.spec]" -@@ -208,27 +208,27 @@ msgstr[0] "配置仓库失败" - msgid "Could not save repo to repofile %s: %s" - msgstr "无法保存仓库至仓库文件 %s:%s" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "y" - msgstr "y" - --#: plugins/copr.py:64 -+#: plugins/copr.py:70 - msgid "yes" - msgstr "是" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "n" - msgstr "n" - --#: plugins/copr.py:65 -+#: plugins/copr.py:71 - msgid "no" - msgstr "否" - --#: plugins/copr.py:84 -+#: plugins/copr.py:92 - msgid "Interact with Copr repositories." - msgstr "与 Copr 仓库交互。" - --#: plugins/copr.py:86 -+#: plugins/copr.py:94 - msgid "" - "\n" - " enable name/project [chroot]\n" -@@ -266,31 +266,31 @@ msgstr "" - " copr search tests\n" - " " - --#: plugins/copr.py:112 -+#: plugins/copr.py:120 - msgid "List all installed Copr repositories (default)" - msgstr "列出所有安装的 Copr 仓库(默认)" - --#: plugins/copr.py:114 -+#: plugins/copr.py:122 - msgid "List enabled Copr repositories" - msgstr "列出启动的 Copr 仓库" - --#: plugins/copr.py:116 -+#: plugins/copr.py:124 - msgid "List disabled Copr repositories" - msgstr "列出禁用的 Copr 仓库" - --#: plugins/copr.py:118 -+#: plugins/copr.py:126 - msgid "List available Copr repositories by user NAME" - msgstr "按照用户 NAME 列出可用的 Copr 仓库" - --#: plugins/copr.py:120 -+#: plugins/copr.py:128 - msgid "Specify an instance of Copr to work with" - msgstr "指定需要使用的 Copr 实例" - --#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 -+#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 - msgid "Error: " - msgstr "错误: " - --#: plugins/copr.py:155 -+#: plugins/copr.py:165 - msgid "" - "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" - "copr_projectname` format" -@@ -298,33 +298,33 @@ msgstr "" - "使用 `--hub` 或使用 `copr_hub/copr_username/copr_projectname` 格式指定 Copr " - "hub" - --#: plugins/copr.py:158 -+#: plugins/copr.py:168 - msgid "multiple hubs specified" - msgstr "指定多个 hub" - --#: plugins/copr.py:223 plugins/copr.py:227 -+#: plugins/copr.py:237 plugins/copr.py:241 - msgid "exactly two additional parameters to copr command are required" - msgstr "Copr 命令要求有且仅有两个额外参数" - --#: plugins/copr.py:232 -+#: plugins/copr.py:246 - msgid "Too many arguments." - msgstr "参数过多。" - --#: plugins/copr.py:235 -+#: plugins/copr.py:249 - msgid "" - "Bad format of optional chroot. The format is distribution-version-" - "architecture." - msgstr "可选 chroot 的错误格式。格式为 distribution-version-architecture。" - --#: plugins/copr.py:250 -+#: plugins/copr.py:264 - msgid "use format `copr_username/copr_projectname` to reference copr project" - msgstr "使用格式 `copr_username/copr_projectname` 来引用 Copr 项目" - --#: plugins/copr.py:252 -+#: plugins/copr.py:266 - msgid "bad copr project format" - msgstr "错误的 Copr 项目格式" - --#: plugins/copr.py:266 -+#: plugins/copr.py:280 - msgid "" - "\n" - "Enabling a Copr repository. Please note that this repository is not part\n" -@@ -352,23 +352,23 @@ msgstr "" - "请不要在 Fedora Bugzilla 中报告这些软件包中出现的\n" - "问题。当出现问题时,请联系仓库的所有者。\n" - --#: plugins/copr.py:283 -+#: plugins/copr.py:297 - msgid "Repository successfully enabled." - msgstr "启用软件仓库成功。" - --#: plugins/copr.py:288 -+#: plugins/copr.py:302 - msgid "Repository successfully disabled." - msgstr "禁用软件仓库成功。" - --#: plugins/copr.py:292 -+#: plugins/copr.py:306 - msgid "Repository successfully removed." - msgstr "软件仓库已成功删除。" - --#: plugins/copr.py:296 plugins/copr.py:697 -+#: plugins/copr.py:310 plugins/copr.py:721 - msgid "Unknown subcommand {}." - msgstr "未知的子命令 {}。" - --#: plugins/copr.py:353 -+#: plugins/copr.py:367 - msgid "" - "* These coprs have repo file with an old format that contains no information " - "about Copr hub - the default one was assumed. Re-enable the project to fix " -@@ -377,48 +377,86 @@ msgstr "" - "* 这些 coprs 有使用旧格式的 repo 文件,它们没有包括 Copr hub 的信息 - 假设使" - "用默认值。重新启用项目来解决这个问题。" - --#: plugins/copr.py:366 -+#: plugins/copr.py:380 - msgid "Can't parse repositories for username '{}'." - msgstr "无法为用户名 username '{}' 解析仓库。" - --#: plugins/copr.py:369 -+#: plugins/copr.py:383 - msgid "List of {} coprs" - msgstr "{} Coprs 列表" - --#: plugins/copr.py:374 -+#: plugins/copr.py:388 - msgid "No description given" - msgstr "没有给出描述" - --#: plugins/copr.py:386 -+#: plugins/copr.py:400 - msgid "Can't parse search for '{}'." - msgstr "无法解析针对 '{}' 的搜索。" - --#: plugins/copr.py:389 -+#: plugins/copr.py:403 - msgid "Matched: {}" - msgstr "匹配:{}" - --#: plugins/copr.py:394 -+#: plugins/copr.py:408 - msgid "No description given." - msgstr "没有给出描述。" - --#: plugins/copr.py:416 -+#: plugins/copr.py:430 - msgid "Safe and good answer. Exiting." - msgstr "安全及明智的答案。退出。" - --#: plugins/copr.py:423 -+#: plugins/copr.py:437 - msgid "This command has to be run under the root user." - msgstr "该命令必须以 root 用户运行。" - --#: plugins/copr.py:485 -+#: plugins/copr.py:487 -+#, python-brace-format -+msgid "Request to {0} failed: {1} - {2}" -+msgstr "请求 {0} 失败:{1} - {2}" -+ -+#: plugins/copr.py:489 -+msgid "It wasn't possible to enable this project.\n" -+msgstr "无法启用此项目。\n" -+ -+#: plugins/copr.py:494 -+#, python-brace-format -+msgid "Repository '{0}' does not exist in project '{1}'." -+msgstr "仓库 '{0}' 在项目 '{1}' 中不存在。" -+ -+#: plugins/copr.py:497 -+msgid "" -+"\n" -+"Available repositories: " -+msgstr "" -+"\n" -+"可用软件仓库: " -+ -+#: plugins/copr.py:499 -+#, python-brace-format - msgid "" --"This repository does not have any builds yet so you cannot enable it now." --msgstr "该仓库尚未包含任何构建所以您现在无法启用它。" -+"\n" -+"\n" -+"If you want to enable a non-default repository, use the following command:\n" -+" 'dnf copr enable {0} '\n" -+"But note that the installed repo file will likely need a manual modification." -+msgstr "" -+"\n" -+"\n" -+"如果需要启用一个非默认的仓库,使用以下命令 :\n" -+" 'dnf copr enable {0} '\n" -+"但请注意,安装的 repo 文件将来可能需要手动修改。" -+ -+#: plugins/copr.py:505 -+#, python-brace-format -+msgid "Project {0} does not exist." -+msgstr "项目 {0} 不存在。" - --#: plugins/copr.py:488 --msgid "Such repository does not exist." --msgstr "该软件仓库不存在。" -+#: plugins/copr.py:508 -+#, python-brace-format -+msgid "Failed to connect to {0}: {1}" -+msgstr "连接到 {0} 失败:{1}" - --#: plugins/copr.py:532 -+#: plugins/copr.py:555 - #, python-brace-format - msgid "" - "Maintainer of the enabled Copr repository decided to make\n" -@@ -447,44 +485,44 @@ msgstr "" - "\n" - "这些仓库已被自动启用。" - --#: plugins/copr.py:553 -+#: plugins/copr.py:576 - msgid "Do you want to keep them enabled?" - msgstr "您需要保持它们被启用吗?" - --#: plugins/copr.py:586 -+#: plugins/copr.py:609 - #, python-brace-format - msgid "Failed to remove copr repo {0}/{1}/{2}" --msgstr "删除 copr 仓库 {0}/{1}/{2} 失败" -+msgstr "无法删除 copr 存储库 {0}/{1}/{2}" - --#: plugins/copr.py:597 -+#: plugins/copr.py:620 - msgid "Failed to disable copr repo {}/{}" --msgstr "无法禁用 Copr 软件仓库 {}/{}" -+msgstr "无法禁用 Copr 存储库 {}/{}" - --#: plugins/copr.py:615 plugins/copr.py:652 -+#: plugins/copr.py:638 plugins/copr.py:675 - msgid "Unknown response from server." - msgstr "来自服务器的未知响应。" - --#: plugins/copr.py:637 -+#: plugins/copr.py:660 - msgid "Interact with Playground repository." - msgstr "与 Playground 仓库交互。" - --#: plugins/copr.py:643 -+#: plugins/copr.py:666 - msgid "Enabling a Playground repository." - msgstr "启用 Playground 仓库。" - --#: plugins/copr.py:644 -+#: plugins/copr.py:667 - msgid "Do you want to continue?" - msgstr "您希望继续吗?" - --#: plugins/copr.py:687 -+#: plugins/copr.py:711 - msgid "Playground repositories successfully enabled." - msgstr "启用 Playground 仓库成功。" - --#: plugins/copr.py:690 -+#: plugins/copr.py:714 - msgid "Playground repositories successfully disabled." - msgstr "禁用 Playground 仓库成功。" - --#: plugins/copr.py:694 -+#: plugins/copr.py:718 - msgid "Playground repositories successfully updated." - msgstr "更新 Playground 仓库成功。" - -@@ -737,7 +775,7 @@ msgstr "软件包规格" - - #: plugins/groups_manager.py:156 - msgid "Can't edit group without specifying it (use --id or --name)" --msgstr "没有指定组(使用 --id 或 --name)就无法编辑组" -+msgstr "没有指定它(使用 --id 或 --name)就不能编辑组" - - #: plugins/groups_manager.py:190 - msgid "Can't load file \"{}\": {}" -@@ -821,7 +859,7 @@ msgstr "只从最新的模块中下载软件包" - #: plugins/modulesync.py:85 - msgid "Unable to find a match for argument: '{}'" - msgid_plural "Unable to find a match for arguments: '{}'" --msgstr[0] "找不到与参数:'{}'相匹配的项" -+msgstr[0] "找不到与参数匹配的项:'{}'" - - #: plugins/modulesync.py:107 - msgid "" -@@ -853,7 +891,7 @@ msgstr "无法满足要求 {}" - msgid "" - "No installed package found for package name \"{pkg}\" specified in needs-" - "restarting file \"{file}\"." --msgstr "未找到在需要重新启动文件 \"{file}\" 中指定的软件包名为 \"{pkg}\" " -+msgstr "未找到在需要重新启动的文件 \"{file}\" 中指定的软件包名为 \"{pkg}\" " - "的已安装的软件包。" - - #: plugins/needs_restarting.py:220 -@@ -899,18 +937,18 @@ msgid "Bad Action Line \"%s\": %s" - msgstr "错误的操作行“ %s”: %s" - - #. unsupported state, skip it --#: plugins/post-transaction-actions.py:130 -+#: plugins/post-transaction-actions.py:133 - #, python-format - msgid "Bad Transaction State: %s" - msgstr "错误的事务状态: %s" - --#: plugins/post-transaction-actions.py:157 --#: plugins/post-transaction-actions.py:159 -+#: plugins/post-transaction-actions.py:160 -+#: plugins/post-transaction-actions.py:162 - #, python-format - msgid "post-transaction-actions: %s" - msgstr "事物后的操作: %s" - --#: plugins/post-transaction-actions.py:161 -+#: plugins/post-transaction-actions.py:164 - #, python-format - msgid "post-transaction-actions: Bad Command \"%s\": %s" - msgstr "事物后的操作 : 无效的命令 \"%s\": %s" -@@ -1087,33 +1125,45 @@ msgstr "管理 RPM 软件包目录" - - #: plugins/repomanage.py:59 - msgid "Pass either --old or --new, not both!" --msgstr "传入 --old 或者 --new,不可同时传入!" -+msgstr "传递 --old 或者 --new,而不是两者都传递!" -+ -+#: plugins/repomanage.py:61 -+msgid "Pass either --oldonly or --new, not both!" -+msgstr "传递 --oldonly 或 --new,而不是两者都传递!" -+ -+#: plugins/repomanage.py:63 -+msgid "Pass either --old or --oldonly, not both!" -+msgstr "传递 --old 或 --oldonly,而不是两者都传递!" - --#: plugins/repomanage.py:89 -+#: plugins/repomanage.py:100 - msgid "No files to process" - msgstr "没有可处理的文件" - --#: plugins/repomanage.py:96 -+#: plugins/repomanage.py:107 - msgid "Could not open {}" - msgstr "无法打开 {}" - --#: plugins/repomanage.py:180 -+#: plugins/repomanage.py:223 - msgid "Print the older packages" - msgstr "打印较旧的软件包" - --#: plugins/repomanage.py:182 -+#: plugins/repomanage.py:225 -+msgid "Print the older packages. Exclude the newest packages." -+msgstr "打印旧的软件包。排除最新的软件包。" -+ -+#: plugins/repomanage.py:227 - msgid "Print the newest packages" - msgstr "打印最新的软件包" - --#: plugins/repomanage.py:184 -+#: plugins/repomanage.py:229 - msgid "Space separated output, not newline" - msgstr "用空格分割输出,而不是新行" - --#: plugins/repomanage.py:186 -+#: plugins/repomanage.py:231 - msgid "Newest N packages to keep - defaults to 1" - msgstr "要保留的最新的 N 个软件包 - 默认值为 1" - --#: plugins/repomanage.py:189 -+#: plugins/repomanage.py:234 - msgid "Path to directory" - msgstr "指向目录的路径" - -@@ -1281,6 +1331,10 @@ msgstr "按原样使用程序包规格,请勿尝试解析它们" - msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." - msgstr "子命令 '{}' 已被弃用。改为使用 'exclude' 子命令。" - -+#~ msgid "" -+#~ "This repository does not have any builds yet so you cannot enable it now." -+#~ msgstr "该仓库尚未包含任何构建所以您现在无法启用它。" -+ - #~ msgid "" - #~ "\n" - #~ "You are about to enable a Playground repository.\n" --- -2.37.3 - diff --git a/SOURCES/0024-builddep-Warning-when-using-macros-with-source-rpms-.patch b/SOURCES/0024-builddep-Warning-when-using-macros-with-source-rpms-.patch new file mode 100644 index 0000000..49e925b --- /dev/null +++ b/SOURCES/0024-builddep-Warning-when-using-macros-with-source-rpms-.patch @@ -0,0 +1,45 @@ +From 0afd47edc60fb7fe5c72fa64bca413bdce82d900 Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +Date: Thu, 11 Aug 2022 14:12:06 +0200 +Subject: [PATCH] builddep: Warning when using macros with source rpms + (RhBug:2077820) + += changelog = +type: bugfix +resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2077820 +--- + doc/builddep.rst | 2 +- + plugins/builddep.py | 4 ++++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/doc/builddep.rst b/doc/builddep.rst +index 6e9bde6..97eb823 100644 +--- a/doc/builddep.rst ++++ b/doc/builddep.rst +@@ -31,7 +31,7 @@ All general DNF options are accepted, see `Options` in :manpage:`dnf(8)` for det + Show this help. + + ``-D , --define `` +- Define the RPM macro named `macro` to the value `expr` when parsing spec files. ++ Define the RPM macro named `macro` to the value `expr` when parsing spec files. Does not apply for source rpm files. + + ``--spec`` + Treat arguments as .spec files. +diff --git a/plugins/builddep.py b/plugins/builddep.py +index e3da012..e7dac43 100644 +--- a/plugins/builddep.py ++++ b/plugins/builddep.py +@@ -204,6 +204,10 @@ class BuildDepCommand(dnf.cli.Command): + err = _("Not all dependencies satisfied") + raise dnf.exceptions.Error(err) + ++ if self.opts.define: ++ logger.warning(_("Warning: -D or --define arguments have no meaning " ++ "for source rpm packages.")) ++ + def _spec_deps(self, spec_fn): + try: + spec = rpm.spec(spec_fn) +-- +2.37.1 + diff --git a/SOURCES/0025-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch b/SOURCES/0025-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch new file mode 100644 index 0000000..82173ab --- /dev/null +++ b/SOURCES/0025-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch @@ -0,0 +1,1711 @@ +From 54eba8059b07b31b2caa27b48269e74da959eaa6 Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +Date: Thu, 22 Sep 2022 16:02:55 +0000 +Subject: [PATCH] Move system-upgrade plugin to core (RhBug:2054235) + += changelog = +type: bugfix +resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2054235 +--- + CMakeLists.txt | 15 + + dnf-plugins-core.spec | 38 +- + doc/CMakeLists.txt | 1 + + doc/conf.py | 1 + + doc/index.rst | 1 + + doc/system-upgrade.rst | 207 ++++++ + etc/CMakeLists.txt | 1 + + etc/systemd/CMakeLists.txt | 1 + + .../dnf-system-upgrade-cleanup.service | 11 + + etc/systemd/dnf-system-upgrade.service | 20 + + plugins/CMakeLists.txt | 1 + + plugins/system_upgrade.py | 699 ++++++++++++++++++ + tests/test_system_upgrade.py | 502 +++++++++++++ + 13 files changed, 1494 insertions(+), 4 deletions(-) + create mode 100644 doc/system-upgrade.rst + create mode 100644 etc/systemd/CMakeLists.txt + create mode 100644 etc/systemd/dnf-system-upgrade-cleanup.service + create mode 100644 etc/systemd/dnf-system-upgrade.service + create mode 100644 plugins/system_upgrade.py + create mode 100644 tests/test_system_upgrade.py + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index f143905..bd5f35b 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -23,6 +23,21 @@ MESSAGE(STATUS "Python install dir is ${PYTHON_INSTALL_DIR}") + + SET (SYSCONFDIR /etc) + ++find_package (PkgConfig) ++ ++if (PKG_CONFIG_FOUND) ++ pkg_search_module (SYSTEMD systemd) ++ if (SYSTEMD_FOUND) ++ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=systemdsystemunitdir systemd ++ OUTPUT_VARIABLE SYSTEMD_DIR ++ OUTPUT_STRIP_TRAILING_WHITESPACE) ++ endif () ++endif() ++ ++if (NOT SYSTEMD_DIR) ++ set (SYSTEMD_DIR /usr/lib/systemd/system) ++endif () ++ + ADD_SUBDIRECTORY (libexec) + ADD_SUBDIRECTORY (doc) + ADD_SUBDIRECTORY (etc) +diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec +index afdbcbb..0e1c9e3 100644 +--- a/dnf-plugins-core.spec ++++ b/dnf-plugins-core.spec +@@ -64,6 +64,9 @@ Provides: dnf-command(repograph) + Provides: dnf-command(repomanage) + Provides: dnf-command(reposync) + Provides: dnf-command(repodiff) ++Provides: dnf-command(system-upgrade) ++Provides: dnf-command(offline-upgrade) ++Provides: dnf-command(offline-distrosync) + Provides: dnf-plugins-extras-debug = %{version}-%{release} + Provides: dnf-plugins-extras-repoclosure = %{version}-%{release} + Provides: dnf-plugins-extras-repograph = %{version}-%{release} +@@ -80,6 +83,7 @@ Provides: dnf-plugin-repodiff = %{version}-%{release} + Provides: dnf-plugin-repograph = %{version}-%{release} + Provides: dnf-plugin-repomanage = %{version}-%{release} + Provides: dnf-plugin-reposync = %{version}-%{release} ++Provides: dnf-plugin-system-upgrade = %{version}-%{release} + %if %{with yumcompatibility} + Provides: yum-plugin-copr = %{version}-%{release} + Provides: yum-plugin-changelog = %{version}-%{release} +@@ -133,8 +137,8 @@ Conflicts: python-%{name} < %{version}-%{release} + %description -n python2-%{name} + Core Plugins for DNF, Python 2 interface. This package enhances DNF with builddep, + config-manager, copr, degug, debuginfo-install, download, needs-restarting, +-groups-manager, repoclosure, repograph, repomanage, reposync, changelog +-and repodiff commands. ++groups-manager, repoclosure, repograph, repomanage, reposync, changelog, ++repodiff, system-upgrade, offline-upgrade and offline-distrosync commands. + Additionally provides generate_completion_cache passive plugin. + %endif + +@@ -145,6 +149,10 @@ Summary: Core Plugins for DNF + BuildRequires: python3-dbus + BuildRequires: python3-devel + BuildRequires: python3-dnf >= %{dnf_lowest_compatible} ++BuildRequires: python3-systemd ++BuildRequires: pkgconfig(systemd) ++BuildRequires: systemd ++%{?systemd_ordering} + %if 0%{?fedora} + Requires: python3-distro + %endif +@@ -152,14 +160,17 @@ Requires: python3-dbus + Requires: python3-dnf >= %{dnf_lowest_compatible} + Requires: python3-hawkey >= %{hawkey_version} + Requires: python3-dateutil ++Requires: python3-systemd + Provides: python3-dnf-plugins-extras-debug = %{version}-%{release} + Provides: python3-dnf-plugins-extras-repoclosure = %{version}-%{release} + Provides: python3-dnf-plugins-extras-repograph = %{version}-%{release} + Provides: python3-dnf-plugins-extras-repomanage = %{version}-%{release} ++Provides: python3-dnf-plugin-system-upgrade = %{version}-%{release} + Obsoletes: python3-dnf-plugins-extras-debug < %{dnf_plugins_extra} + Obsoletes: python3-dnf-plugins-extras-repoclosure < %{dnf_plugins_extra} + Obsoletes: python3-dnf-plugins-extras-repograph < %{dnf_plugins_extra} + Obsoletes: python3-dnf-plugins-extras-repomanage < %{dnf_plugins_extra} ++Obsoletes: python3-dnf-plugin-system-upgrade < %{version}-%{release} + + Conflicts: %{name} <= 0.1.5 + # let the both python plugin versions be updated simultaneously +@@ -169,8 +180,8 @@ Conflicts: python-%{name} < %{version}-%{release} + %description -n python3-%{name} + Core Plugins for DNF, Python 3 interface. This package enhances DNF with builddep, + config-manager, copr, debug, debuginfo-install, download, needs-restarting, +-groups-manager, repoclosure, repograph, repomanage, reposync, changelog +-and repodiff commands. ++groups-manager, repoclosure, repograph, repomanage, reposync, changelog, ++repodiff, system-upgrade, offline-upgrade and offline-distrosync commands. + Additionally provides generate_completion_cache passive plugin. + %endif + +@@ -451,6 +462,17 @@ pushd build-py3 + %make_install + popd + %endif ++ ++%if %{with python3} ++mkdir -p %{buildroot}%{_unitdir}/system-update.target.wants/ ++pushd %{buildroot}%{_unitdir}/system-update.target.wants/ ++ ln -sr ../dnf-system-upgrade.service ++popd ++ ++ln -sf %{_mandir}/man8/dnf-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf-offline-upgrade.8.gz ++ln -sf %{_mandir}/man8/dnf-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf-offline-distrosync.8.gz ++%endif ++ + %find_lang %{name} + %if %{with yumutils} + %if %{with python3} +@@ -515,6 +537,9 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ + %{_mandir}/man8/dnf-repograph.* + %{_mandir}/man8/dnf-repomanage.* + %{_mandir}/man8/dnf-reposync.* ++%{_mandir}/man8/dnf-system-upgrade.* ++%{_mandir}/man8/dnf-offline-upgrade.* ++%{_mandir}/man8/dnf-offline-distrosync.* + %if %{with yumcompatibility} + %{_mandir}/man1/yum-changelog.* + %{_mandir}/man8/yum-copr.* +@@ -572,6 +597,7 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ + %{python3_sitelib}/dnf-plugins/repograph.py + %{python3_sitelib}/dnf-plugins/repomanage.py + %{python3_sitelib}/dnf-plugins/reposync.py ++%{python3_sitelib}/dnf-plugins/system_upgrade.py + %{python3_sitelib}/dnf-plugins/__pycache__/builddep.* + %{python3_sitelib}/dnf-plugins/__pycache__/changelog.* + %{python3_sitelib}/dnf-plugins/__pycache__/config_manager.* +@@ -587,7 +613,11 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ + %{python3_sitelib}/dnf-plugins/__pycache__/repograph.* + %{python3_sitelib}/dnf-plugins/__pycache__/repomanage.* + %{python3_sitelib}/dnf-plugins/__pycache__/reposync.* ++%{python3_sitelib}/dnf-plugins/__pycache__/system_upgrade.* + %{python3_sitelib}/dnfpluginscore/ ++%{_unitdir}/dnf-system-upgrade.service ++%{_unitdir}/dnf-system-upgrade-cleanup.service ++%{_unitdir}/system-update.target.wants/dnf-system-upgrade.service + %endif + + %if %{with yumutils} +diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt +index ff84cf8..79472a5 100644 +--- a/doc/CMakeLists.txt ++++ b/doc/CMakeLists.txt +@@ -37,6 +37,7 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/dnf-builddep.8 + ${CMAKE_CURRENT_BINARY_DIR}/dnf-reposync.8 + ${CMAKE_CURRENT_BINARY_DIR}/dnf-post-transaction-actions.8 + ${CMAKE_CURRENT_BINARY_DIR}/dnf-show-leaves.8 ++ ${CMAKE_CURRENT_BINARY_DIR}/dnf-system-upgrade.8 + ${CMAKE_CURRENT_BINARY_DIR}/dnf-versionlock.8 + ${CMAKE_CURRENT_BINARY_DIR}/yum-copr.8 + ${CMAKE_CURRENT_BINARY_DIR}/yum-versionlock.8 +diff --git a/doc/conf.py b/doc/conf.py +index 41d6936..327ac07 100644 +--- a/doc/conf.py ++++ b/doc/conf.py +@@ -264,6 +264,7 @@ man_pages = [ + ('post-transaction-actions', 'dnf-post-transaction-actions', + u'DNF post transaction actions Plugin', AUTHORS, 8), + ('show-leaves', 'dnf-show-leaves', u'DNF show-leaves Plugin', AUTHORS, 8), ++ ('system-upgrade', 'dnf-system-upgrade', u'DNF system-upgrade Plugin', AUTHORS, 8), + ('versionlock', 'dnf-versionlock', u'DNF versionlock Plugin', AUTHORS, 8), + + # yum3 compatible layer for manpages +diff --git a/doc/index.rst b/doc/index.rst +index 07f6052..251a24e 100644 +--- a/doc/index.rst ++++ b/doc/index.rst +@@ -46,6 +46,7 @@ This documents core plugins of DNF: + repomanage + reposync + show-leaves ++ system-upgrade + versionlock + + +diff --git a/doc/system-upgrade.rst b/doc/system-upgrade.rst +new file mode 100644 +index 0000000..3110460 +--- /dev/null ++++ b/doc/system-upgrade.rst +@@ -0,0 +1,207 @@ ++.. ++ Copyright (C) 2014-2016 Red Hat, Inc. ++ ++ This copyrighted material is made available to anyone wishing to use, ++ modify, copy, or redistribute it subject to the terms and conditions of ++ the GNU General Public License v.2, or (at your option) any later version. ++ This program is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY expressed or implied, including the implied warranties of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General ++ Public License for more details. You should have received a copy of the ++ GNU General Public License along with this program; if not, write to the ++ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ 02110-1301, USA. Any Red Hat trademarks that are incorporated in the ++ source code or documentation are not subject to the GNU General Public ++ License and may only be used or replicated with the express permission of ++ Red Hat, Inc. ++ ++========================= ++DNF system-upgrade Plugin ++========================= ++ ++----------- ++Description ++----------- ++ ++DNF system-upgrades plugin provides three commands: ``system-upgrade``, ``offline-upgrade``, and ++``offline-distrosync``. Only ``system-upgrade`` command requires increase of distribution major ++version (``--releasever``) compared to installed version. ++ ++``dnf system-upgrade`` can be used to upgrade a Fedora system to a new major ++release. It replaces fedup (the old Fedora Upgrade tool). Before you proceed ensure that your system ++is fully upgraded (``dnf --refresh upgrade``). ++ ++The ``system-upgrade`` command also performes additional actions necessary for the upgrade of the ++system, for example an upgrade of groups and environments. ++ ++-------- ++Synopsis ++-------- ++ ++``dnf system-upgrade download --releasever VERSION [OPTIONS]`` ++ ++``dnf system-upgrade reboot`` ++ ++``dnf system-upgrade clean`` ++ ++``dnf system-upgrade log`` ++ ++``dnf system-upgrade log --number=`` ++ ++``dnf offline-upgrade download [OPTIONS]`` ++ ++``dnf offline-upgrade reboot`` ++ ++``dnf offline-upgrade clean`` ++ ++``dnf offline-upgrade log`` ++ ++``dnf offline-upgrade log --number=`` ++ ++``dnf offline-distrosync download [OPTIONS]`` ++ ++``dnf offline-distrosync reboot`` ++ ++``dnf offline-distrosync clean`` ++ ++``dnf offline-distrosync log`` ++ ++``dnf offline-distrosync log --number=`` ++ ++----------- ++Subcommands ++----------- ++ ++``download`` ++ Downloads everything needed to upgrade to a new major release. ++ ++``reboot`` ++ Prepares the system to perform the upgrade, and reboots to start the upgrade. ++ This can only be used after the ``download`` command completes successfully. ++ ++``clean`` ++ Remove previously-downloaded data. This happens automatically at the end of ++ a successful upgrade. ++ ++``log`` ++ Used to see a list of boots during which an upgrade was attempted, or show ++ the logs from an upgrade attempt. The logs for one of the boots can be shown ++ by specifying one of the numbers in the first column. Negative numbers can ++ be used to number the boots from last to first. For example, ``log --number=-1`` can ++ be used to see the logs for the last upgrade attempt. ++ ++------- ++Options ++------- ++ ++``--releasever=VERSION`` ++ REQUIRED. The version to upgrade to. Sets ``$releasever`` in all enabled ++ repos. Usually a number, or ``rawhide``. ++ ++``--downloaddir=`` ++ Redirect download of packages to provided ````. By default, packages ++ are downloaded into (per repository created) subdirectories of ++ /var/lib/dnf/system-upgrade. ++ ++``--distro-sync`` ++ Behave like ``dnf distro-sync``: always install packages from the new ++ release, even if they are older than the currently-installed version. This ++ is the default behavior. ++ ++``--no-downgrade`` ++ Behave like ``dnf update``: do not install packages from the new release ++ if they are older than what is currently installed. This is the opposite of ++ ``--distro-sync``. If both are specified, the last option will be used. The option cannot be ++ used with the ``offline-distrosync`` command. ++ ++``--number`` ++ Applied with ``log`` subcommand will show the log specified by the number. ++ ++----- ++Notes ++----- ++ ++``dnf system-upgrade reboot`` does not create a "System Upgrade" boot item. The ++upgrade will start regardless of which boot item is chosen. ++ ++The ``DNF_SYSTEM_UPGRADE_NO_REBOOT`` environment variable can be set to a ++non-empty value to disable the actual reboot performed by ``system-upgrade`` ++(e.g. for testing purposes). ++ ++Since this is a DNF plugin, options accepted by ``dnf`` are also valid here, ++such as ``--allowerasing``. ++See :manpage:`dnf(8)` for more information. ++ ++The ``fedup`` command is not provided, not even as an alias for ++``dnf system-upgrade``. ++ ++---- ++Bugs ++---- ++ ++Upgrading from install media (e.g. a DVD or .iso file) currently requires the ++user to manually set up a DNF repo and fstab entry for the media. ++ ++-------- ++Examples ++-------- ++ ++Typical upgrade usage ++--------------------- ++ ++``dnf --refresh upgrade`` ++ ++``dnf system-upgrade download --releasever 26`` ++ ++``dnf system-upgrade reboot`` ++ ++Show logs from last upgrade attempt ++----------------------------------- ++ ++``dnf system-upgrade log --number=-1`` ++ ++-------------- ++Reporting Bugs ++-------------- ++ ++Bugs should be filed here: ++ ++ https://bugzilla.redhat.com/ ++ ++For more info on filing bugs, see the Fedora Project wiki: ++ ++ https://fedoraproject.org/wiki/How_to_file_a_bug_report ++ ++ https://fedoraproject.org/wiki/Bugs_and_feature_requests ++ ++Please include ``/var/log/dnf.log`` and the output of ++``dnf system-upgrade log --number=-1`` (if applicable) in your bug reports. ++ ++Problems with dependency solving during download are best reported to the ++maintainers of the package(s) with the dependency problems. ++ ++Similarly, problems encountered on your system after the upgrade completes ++should be reported to the maintainers of the affected components. In other ++words: if (for example) KDE stops working, it's best if you report that to ++the KDE maintainers. ++ ++-------- ++See Also ++-------- ++ ++:manpage:`dnf(8)`, ++:manpage:`dnf.conf(5)`, ++:manpage:`journalctl(1)`. ++ ++Project homepage ++---------------- ++ ++https://github.com/rpm-software-management/dnf-plugins-core ++ ++------- ++Authors ++------- ++ ++Will Woods ++ ++Štěpán Smetana +diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt +index 2e9cccd..a892f8a 100644 +--- a/etc/CMakeLists.txt ++++ b/etc/CMakeLists.txt +@@ -1 +1,2 @@ + ADD_SUBDIRECTORY (dnf) ++ADD_SUBDIRECTORY (systemd) +diff --git a/etc/systemd/CMakeLists.txt b/etc/systemd/CMakeLists.txt +new file mode 100644 +index 0000000..8a29403 +--- /dev/null ++++ b/etc/systemd/CMakeLists.txt +@@ -0,0 +1 @@ ++INSTALL (FILES "dnf-system-upgrade.service" "dnf-system-upgrade-cleanup.service" DESTINATION ${SYSTEMD_DIR}) +diff --git a/etc/systemd/dnf-system-upgrade-cleanup.service b/etc/systemd/dnf-system-upgrade-cleanup.service +new file mode 100644 +index 0000000..49f771c +--- /dev/null ++++ b/etc/systemd/dnf-system-upgrade-cleanup.service +@@ -0,0 +1,11 @@ ++[Unit] ++Description=System Upgrade using DNF failed ++DefaultDependencies=no ++ ++[Service] ++Type=oneshot ++# Remove the symlink if it's still there, to protect against reboot loops. ++ExecStart=/usr/bin/rm -fv /system-update ++# If anything goes wrong, reboot back to the normal system. ++ExecStart=/usr/bin/systemctl --no-block reboot ++ +diff --git a/etc/systemd/dnf-system-upgrade.service b/etc/systemd/dnf-system-upgrade.service +new file mode 100644 +index 0000000..2d23cfe +--- /dev/null ++++ b/etc/systemd/dnf-system-upgrade.service +@@ -0,0 +1,20 @@ ++[Unit] ++Description=System Upgrade using DNF ++ConditionPathExists=/system-update ++Documentation=http://www.freedesktop.org/wiki/Software/systemd/SystemUpdates ++ ++DefaultDependencies=no ++Requires=sysinit.target ++After=sysinit.target systemd-journald.socket system-update-pre.target ++Before=shutdown.target system-update.target ++OnFailure=dnf-system-upgrade-cleanup.service ++ ++[Service] ++# We are done when the script exits, not before ++Type=oneshot ++# Upgrade output goes to journal and on-screen. ++StandardOutput=journal+console ++ExecStart=/usr/bin/dnf system-upgrade upgrade ++ ++[Install] ++WantedBy=system-update.target +diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt +index 59f148f..d004e5e 100644 +--- a/plugins/CMakeLists.txt ++++ b/plugins/CMakeLists.txt +@@ -22,6 +22,7 @@ INSTALL (FILES repograph.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + INSTALL (FILES repomanage.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + INSTALL (FILES reposync.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + INSTALL (FILES show_leaves.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) ++INSTALL (FILES system_upgrade.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + INSTALL (FILES modulesync.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + INSTALL (FILES versionlock.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins) + +diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py +new file mode 100644 +index 0000000..fee6762 +--- /dev/null ++++ b/plugins/system_upgrade.py +@@ -0,0 +1,699 @@ ++# -*- coding: utf-8 -*- ++# ++# Copyright (c) 2015-2020 Red Hat, Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License along ++# with this program. If not, see . ++# ++# Author(s): Will Woods ++ ++"""system_upgrade.py - DNF plugin to handle major-version system upgrades.""" ++ ++from subprocess import call, Popen, check_output, CalledProcessError ++import json ++import os ++import os.path ++import re ++import sys ++import uuid ++ ++from systemd import journal ++ ++from dnfpluginscore import _, logger ++ ++import dnf ++import dnf.cli ++from dnf.cli import CliError ++from dnf.i18n import ucd ++import dnf.transaction ++from dnf.transaction_sr import serialize_transaction, TransactionReplay ++ ++import libdnf.conf ++ ++ ++# Translators: This string is only used in unit tests. ++_("the color of the sky") ++ ++DOWNLOAD_FINISHED_ID = uuid.UUID('9348174c5cc74001a71ef26bd79d302e') ++REBOOT_REQUESTED_ID = uuid.UUID('fef1cc509d5047268b83a3a553f54b43') ++UPGRADE_STARTED_ID = uuid.UUID('3e0a5636d16b4ca4bbe5321d06c6aa62') ++UPGRADE_FINISHED_ID = uuid.UUID('8cec00a1566f4d3594f116450395f06c') ++ ++ID_TO_IDENTIFY_BOOTS = UPGRADE_STARTED_ID ++ ++PLYMOUTH = '/usr/bin/plymouth' ++ ++RELEASEVER_MSG = _( ++ "Need a --releasever greater than the current system version.") ++DOWNLOAD_FINISHED_MSG = _( # Translators: do not change "reboot" here ++ "Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++ "To remove cached metadata and transaction use 'dnf {command} clean'") ++CANT_RESET_RELEASEVER = _( ++ "Sorry, you need to use 'download --releasever' instead of '--network'") ++ ++STATE_VERSION = 2 ++ ++# --- Miscellaneous helper functions ------------------------------------------ ++ ++ ++def reboot(): ++ if os.getenv("DNF_SYSTEM_UPGRADE_NO_REBOOT", default=False): ++ logger.info(_("Reboot turned off, not rebooting.")) ++ else: ++ Popen(["systemctl", "reboot"]) ++ ++ ++def get_url_from_os_release(): ++ key = "UPGRADE_GUIDE_URL=" ++ for path in ["/etc/os-release", "/usr/lib/os-release"]: ++ try: ++ with open(path) as release_file: ++ for line in release_file: ++ line = line.strip() ++ if line.startswith(key): ++ return line[len(key):].strip('"') ++ except IOError: ++ continue ++ return None ++ ++ ++# DNF-FIXME: dnf.util.clear_dir() doesn't delete regular files :/ ++def clear_dir(path, ignore=[]): ++ if not os.path.isdir(path): ++ return ++ ++ for entry in os.listdir(path): ++ fullpath = os.path.join(path, entry) ++ if fullpath in ignore: ++ continue ++ try: ++ if os.path.isdir(fullpath): ++ dnf.util.rm_rf(fullpath) ++ else: ++ os.unlink(fullpath) ++ except OSError: ++ pass ++ ++ ++def check_release_ver(conf, target=None): ++ if dnf.rpm.detect_releasever(conf.installroot) == conf.releasever: ++ raise CliError(RELEASEVER_MSG) ++ if target and target != conf.releasever: ++ # it's too late to set releasever here, so this can't work. ++ # (see https://bugzilla.redhat.com/show_bug.cgi?id=1212341) ++ raise CliError(CANT_RESET_RELEASEVER) ++ ++ ++def disable_blanking(): ++ try: ++ tty = open('/dev/tty0', 'wb') ++ tty.write(b'\33[9;0]') ++ except Exception as e: ++ print(_("Screen blanking can't be disabled: %s") % e) ++ ++# --- State object - for tracking upgrade state between runs ------------------ ++ ++ ++# DNF-INTEGRATION-NOTE: basically the same thing as dnf.persistor.JSONDB ++class State(object): ++ def __init__(self, statefile): ++ self.statefile = statefile ++ self._data = {} ++ self._read() ++ ++ def _read(self): ++ try: ++ with open(self.statefile) as fp: ++ self._data = json.load(fp) ++ except IOError: ++ self._data = {} ++ except ValueError: ++ self._data = {} ++ logger.warning(_("Failed loading state file: %s, continuing with " ++ "empty state."), self.statefile) ++ ++ def write(self): ++ dnf.util.ensure_dir(os.path.dirname(self.statefile)) ++ with open(self.statefile, 'w') as outf: ++ json.dump(self._data, outf, indent=4, sort_keys=True) ++ ++ def clear(self): ++ if os.path.exists(self.statefile): ++ os.unlink(self.statefile) ++ self._read() ++ ++ def __enter__(self): ++ return self ++ ++ def __exit__(self, exc_type, exc_value, traceback): ++ if exc_type is None: ++ self.write() ++ ++ # helper function for creating properties. pylint: disable=protected-access ++ def _prop(option): # pylint: disable=no-self-argument ++ def setprop(self, value): ++ self._data[option] = value ++ ++ def getprop(self): ++ return self._data.get(option) ++ return property(getprop, setprop) ++ ++ # !!! Increase STATE_VERSION for any changes in data structure like a new property or a new ++ # data structure !!! ++ state_version = _prop("state_version") ++ download_status = _prop("download_status") ++ destdir = _prop("destdir") ++ target_releasever = _prop("target_releasever") ++ system_releasever = _prop("system_releasever") ++ gpgcheck = _prop("gpgcheck") ++ # list of repos with gpgcheck=True ++ gpgcheck_repos = _prop("gpgcheck_repos") ++ # list of repos with repo_gpgcheck=True ++ repo_gpgcheck_repos = _prop("repo_gpgcheck_repos") ++ upgrade_status = _prop("upgrade_status") ++ upgrade_command = _prop("upgrade_command") ++ distro_sync = _prop("distro_sync") ++ enable_disable_repos = _prop("enable_disable_repos") ++ module_platform_id = _prop("module_platform_id") ++ ++# --- Plymouth output helpers ------------------------------------------------- ++ ++ ++class PlymouthOutput(object): ++ """A plymouth output helper class. ++ ++ Filters duplicate calls, and stops calling the plymouth binary if we ++ fail to contact it. ++ """ ++ ++ def __init__(self): ++ self.alive = True ++ self._last_args = dict() ++ self._last_msg = None ++ ++ def _plymouth(self, cmd, *args): ++ dupe_cmd = (args == self._last_args.get(cmd)) ++ if (self.alive and not dupe_cmd) or cmd == '--ping': ++ try: ++ self.alive = (call((PLYMOUTH, cmd) + args) == 0) ++ except OSError: ++ self.alive = False ++ self._last_args[cmd] = args ++ return self.alive ++ ++ def ping(self): ++ return self._plymouth("--ping") ++ ++ def message(self, msg): ++ if self._last_msg and self._last_msg != msg: ++ self._plymouth("hide-message", "--text", self._last_msg) ++ self._last_msg = msg ++ return self._plymouth("display-message", "--text", msg) ++ ++ def set_mode(self): ++ mode = 'updates' ++ try: ++ s = check_output([PLYMOUTH, '--help']) ++ if re.search('--system-upgrade', ucd(s)): ++ mode = 'system-upgrade' ++ except (CalledProcessError, OSError): ++ pass ++ return self._plymouth("change-mode", "--" + mode) ++ ++ def progress(self, percent): ++ return self._plymouth("system-update", "--progress", str(percent)) ++ ++ ++# A single PlymouthOutput instance for us to use within this module ++Plymouth = PlymouthOutput() ++ ++ ++# A TransactionProgress class that updates plymouth for us. ++class PlymouthTransactionProgress(dnf.callback.TransactionProgress): ++ ++ # pylint: disable=too-many-arguments ++ def progress(self, package, action, ti_done, ti_total, ts_done, ts_total): ++ self._update_plymouth(package, action, ts_done, ts_total) ++ ++ def _update_plymouth(self, package, action, current, total): ++ # Prevents quick jumps of progressbar when pretrans scriptlets ++ # and TRANS_PREPARATION are reported as 1/1 ++ if total == 1: ++ return ++ # Verification goes through all the packages again, ++ # which resets the "current" param value, this prevents ++ # resetting of the progress bar as well. (Rhbug:1809096) ++ if action != dnf.callback.PKG_VERIFY: ++ Plymouth.progress(int(90.0 * current / total)) ++ else: ++ Plymouth.progress(90 + int(10.0 * current / total)) ++ ++ Plymouth.message(self._fmt_event(package, action, current, total)) ++ ++ def _fmt_event(self, package, action, current, total): ++ action = dnf.transaction.ACTIONS.get(action, action) ++ return "[%d/%d] %s %s..." % (current, total, action, package) ++ ++# --- journal helpers ------------------------------------------------- ++ ++ ++def find_boots(message_id): ++ """Find all boots with this message id. ++ ++ Returns the entries of all found boots. ++ """ ++ j = journal.Reader() ++ j.add_match(MESSAGE_ID=message_id.hex, # identify the message ++ _UID=0) # prevent spoofing of logs ++ ++ oldboot = None ++ for entry in j: ++ boot = entry['_BOOT_ID'] ++ if boot == oldboot: ++ continue ++ oldboot = boot ++ yield entry ++ ++ ++def list_logs(): ++ print(_('The following boots appear to contain upgrade logs:')) ++ n = -1 ++ for n, entry in enumerate(find_boots(ID_TO_IDENTIFY_BOOTS)): ++ print('{} / {.hex}: {:%Y-%m-%d %H:%M:%S} {}→{}'.format( ++ n + 1, ++ entry['_BOOT_ID'], ++ entry['__REALTIME_TIMESTAMP'], ++ entry.get('SYSTEM_RELEASEVER', '??'), ++ entry.get('TARGET_RELEASEVER', '??'))) ++ if n == -1: ++ print(_('-- no logs were found --')) ++ ++ ++def pick_boot(message_id, n): ++ boots = list(find_boots(message_id)) ++ # Positive indices index all found boots starting with 1 and going forward, ++ # zero is the current boot, and -1, -2, -3 are previous going backwards. ++ # This is the same as journalctl. ++ try: ++ if n == 0: ++ raise IndexError ++ if n > 0: ++ n -= 1 ++ return boots[n]['_BOOT_ID'] ++ except IndexError: ++ raise CliError(_("Cannot find logs with this index.")) ++ ++ ++def show_log(n): ++ boot_id = pick_boot(ID_TO_IDENTIFY_BOOTS, n) ++ process = Popen(['journalctl', '--boot', boot_id.hex]) ++ process.wait() ++ rc = process.returncode ++ if rc == 1: ++ raise dnf.exceptions.Error(_("Unable to match systemd journal entry")) ++ ++ ++CMDS = ['download', 'clean', 'reboot', 'upgrade', 'log'] ++ ++# --- The actual Plugin and Command objects! ---------------------------------- ++ ++ ++class SystemUpgradePlugin(dnf.Plugin): ++ name = 'system-upgrade' ++ ++ def __init__(self, base, cli): ++ super(SystemUpgradePlugin, self).__init__(base, cli) ++ if cli: ++ cli.register_command(SystemUpgradeCommand) ++ cli.register_command(OfflineUpgradeCommand) ++ cli.register_command(OfflineDistrosyncCommand) ++ ++ ++class SystemUpgradeCommand(dnf.cli.Command): ++ aliases = ('system-upgrade', 'fedup',) ++ summary = _("Prepare system for upgrade to a new release") ++ ++ DATADIR = 'var/lib/dnf/system-upgrade' ++ ++ def __init__(self, cli): ++ super(SystemUpgradeCommand, self).__init__(cli) ++ self.datadir = os.path.join(cli.base.conf.installroot, self.DATADIR) ++ self.transaction_file = os.path.join(self.datadir, 'system-upgrade-transaction.json') ++ self.magic_symlink = os.path.join(cli.base.conf.installroot, 'system-update') ++ ++ self.state = State(os.path.join(self.datadir, 'system-upgrade-state.json')) ++ ++ @staticmethod ++ def set_argparser(parser): ++ parser.add_argument("--no-downgrade", dest='distro_sync', ++ action='store_false', ++ help=_("keep installed packages if the new " ++ "release's version is older")) ++ parser.add_argument('tid', nargs=1, choices=CMDS, ++ metavar="[%s]" % "|".join(CMDS)) ++ parser.add_argument('--number', type=int, help=_('which logs to show')) ++ ++ def log_status(self, message, message_id): ++ """Log directly to the journal.""" ++ journal.send(message, ++ MESSAGE_ID=message_id, ++ PRIORITY=journal.LOG_NOTICE, ++ SYSTEM_RELEASEVER=self.state.system_releasever, ++ TARGET_RELEASEVER=self.state.target_releasever, ++ DNF_VERSION=dnf.const.VERSION) ++ ++ def pre_configure(self): ++ self._call_sub("check") ++ self._call_sub("pre_configure") ++ ++ def configure(self): ++ self._call_sub("configure") ++ ++ def run(self): ++ self._call_sub("run") ++ ++ def run_transaction(self): ++ self._call_sub("transaction") ++ ++ def run_resolved(self): ++ self._call_sub("resolved") ++ ++ def _call_sub(self, name): ++ subfunc = getattr(self, name + '_' + self.opts.tid[0], None) ++ if callable(subfunc): ++ subfunc() ++ ++ def _check_state_version(self, command): ++ if self.state.state_version != STATE_VERSION: ++ msg = _("Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++ "").format(command=command) ++ raise CliError(msg) ++ ++ def _set_cachedir(self): ++ # set download directories from json state file ++ self.base.conf.cachedir = self.datadir ++ self.base.conf.destdir = self.state.destdir if self.state.destdir else None ++ ++ def _get_forward_reverse_pkg_reason_pairs(self): ++ """ ++ forward = {repoid:{pkg_nevra: {tsi.action: tsi.reason}} ++ reverse = {pkg_nevra: {tsi.action: tsi.reason}} ++ :return: forward, reverse ++ """ ++ backward_action = set(dnf.transaction.BACKWARD_ACTIONS + [libdnf.transaction.TransactionItemAction_REINSTALLED]) ++ forward_actions = set(dnf.transaction.FORWARD_ACTIONS) ++ ++ forward = {} ++ reverse = {} ++ for tsi in self.cli.base.transaction: ++ if tsi.action in forward_actions: ++ pkg = tsi.pkg ++ forward.setdefault(pkg.repo.id, {}).setdefault( ++ str(pkg), {})[tsi.action] = tsi.reason ++ elif tsi.action in backward_action: ++ reverse.setdefault(str(tsi.pkg), {})[tsi.action] = tsi.reason ++ return forward, reverse ++ ++ # == pre_configure_*: set up action-specific demands ========================== ++ def pre_configure_download(self): ++ # only download subcommand accepts --destdir command line option ++ self.base.conf.cachedir = self.datadir ++ self.base.conf.destdir = self.opts.destdir if self.opts.destdir else None ++ if 'offline-distrosync' == self.opts.command and not self.opts.distro_sync: ++ raise CliError( ++ _("Command 'offline-distrosync' cannot be used with --no-downgrade option")) ++ elif 'offline-upgrade' == self.opts.command: ++ self.opts.distro_sync = False ++ ++ def pre_configure_reboot(self): ++ self._set_cachedir() ++ ++ def pre_configure_upgrade(self): ++ self._set_cachedir() ++ if self.state.enable_disable_repos: ++ self.opts.repos_ed = self.state.enable_disable_repos ++ self.base.conf.releasever = self.state.target_releasever ++ ++ def pre_configure_clean(self): ++ self._set_cachedir() ++ ++ # == configure_*: set up action-specific demands ========================== ++ ++ def configure_download(self): ++ if 'system-upgrade' == self.opts.command or 'fedup' == self.opts.command: ++ help_url = get_url_from_os_release() ++ if help_url: ++ msg = _('Additional information for System Upgrade: {}') ++ logger.info(msg.format(ucd(help_url))) ++ if self.base._promptWanted(): ++ msg = _('Before you continue ensure that your system is fully upgraded by running ' ++ '"dnf --refresh upgrade". Do you want to continue') ++ if self.base.conf.assumeno or not self.base.output.userconfirm( ++ msg='{} [y/N]: '.format(msg), defaultyes_msg='{} [Y/n]: '.format(msg)): ++ logger.error(_("Operation aborted.")) ++ sys.exit(1) ++ check_release_ver(self.base.conf, target=self.opts.releasever) ++ self.cli.demands.root_user = True ++ self.cli.demands.resolving = True ++ self.cli.demands.available_repos = True ++ self.cli.demands.sack_activation = True ++ self.cli.demands.freshest_metadata = True ++ # We want to do the depsolve / download / transaction-test, but *not* ++ # run the actual RPM transaction to install the downloaded packages. ++ # Setting the "test" flag makes the RPM transaction a test transaction, ++ # so nothing actually gets installed. ++ # (It also means that we run two test transactions in a row, which is ++ # kind of silly, but that's something for DNF to fix...) ++ self.base.conf.tsflags += ["test"] ++ ++ def configure_reboot(self): ++ # FUTURE: add a --debug-shell option to enable debug shell: ++ # systemctl add-wants system-update.target debug-shell.service ++ self.cli.demands.root_user = True ++ ++ def configure_upgrade(self): ++ # same as the download, but offline and non-interactive. so... ++ self.cli.demands.root_user = True ++ self.cli.demands.resolving = True ++ self.cli.demands.available_repos = True ++ self.cli.demands.sack_activation = True ++ # use the saved value for --allowerasing, etc. ++ self.opts.distro_sync = self.state.distro_sync ++ if self.state.gpgcheck is not None: ++ self.base.conf.gpgcheck = self.state.gpgcheck ++ if self.state.gpgcheck_repos is not None: ++ for repo in self.base.repos.values(): ++ repo.gpgcheck = repo.id in self.state.gpgcheck_repos ++ if self.state.repo_gpgcheck_repos is not None: ++ for repo in self.base.repos.values(): ++ repo.repo_gpgcheck = repo.id in self.state.repo_gpgcheck_repos ++ self.base.conf.module_platform_id = self.state.module_platform_id ++ # don't try to get new metadata, 'cuz we're offline ++ self.cli.demands.cacheonly = True ++ # and don't ask any questions (we confirmed all this beforehand) ++ self.base.conf.assumeyes = True ++ self.cli.demands.transaction_display = PlymouthTransactionProgress() ++ # upgrade operation already removes all element that must be removed. Additional removal ++ # could trigger unwanted changes in transaction. ++ self.base.conf.clean_requirements_on_remove = False ++ self.base.conf.install_weak_deps = False ++ ++ def configure_clean(self): ++ self.cli.demands.root_user = True ++ ++ def configure_log(self): ++ pass ++ ++ # == check_*: do any action-specific checks =============================== ++ ++ def check_reboot(self): ++ if not self.state.download_status == 'complete': ++ raise CliError(_("system is not ready for upgrade")) ++ self._check_state_version(self.opts.command) ++ if self.state.upgrade_command != self.opts.command: ++ msg = _("the transaction was not prepared for '{command}'. " ++ "Rerun 'dnf {command} download [OPTIONS]'").format(command=self.opts.command) ++ raise CliError(msg) ++ if os.path.lexists(self.magic_symlink): ++ raise CliError(_("upgrade is already scheduled")) ++ dnf.util.ensure_dir(self.datadir) ++ # FUTURE: checkRPMDBStatus(self.state.download_transaction_id) ++ ++ def check_upgrade(self): ++ if not os.path.lexists(self.magic_symlink): ++ logger.info(_("trigger file does not exist. exiting quietly.")) ++ raise SystemExit(0) ++ if os.readlink(self.magic_symlink) != self.datadir: ++ logger.info(_("another upgrade tool is running. exiting quietly.")) ++ raise SystemExit(0) ++ # Delete symlink ASAP to avoid reboot loops ++ dnf.yum.misc.unlink_f(self.magic_symlink) ++ command = self.state.upgrade_command ++ if not command: ++ command = self.opts.command ++ self._check_state_version(command) ++ if not self.state.upgrade_status == 'ready': ++ msg = _("use 'dnf {command} reboot' to begin the upgrade").format(command=command) ++ raise CliError(msg) ++ ++ # == run_*: run the action/prep the transaction =========================== ++ ++ def run_prepare(self): ++ # make the magic symlink ++ os.symlink(self.datadir, self.magic_symlink) ++ # set upgrade_status so that the upgrade can run ++ with self.state as state: ++ state.upgrade_status = 'ready' ++ ++ def run_reboot(self): ++ self.run_prepare() ++ ++ if not self.opts.tid[0] == "reboot": ++ return ++ ++ self.log_status(_("Rebooting to perform upgrade."), ++ REBOOT_REQUESTED_ID) ++ reboot() ++ ++ def run_download(self): ++ # Mark everything in the world for upgrade/sync ++ if self.opts.distro_sync: ++ self.base.distro_sync() ++ else: ++ self.base.upgrade_all() ++ ++ if self.opts.command not in ['offline-upgrade', 'offline-distrosync']: ++ # Mark all installed groups and environments for upgrade ++ self.base.read_comps() ++ installed_groups = [g.id for g in self.base.comps.groups if self.base.history.group.get(g.id)] ++ if installed_groups: ++ self.base.env_group_upgrade(installed_groups) ++ installed_environments = [g.id for g in self.base.comps.environments if self.base.history.env.get(g.id)] ++ if installed_environments: ++ self.base.env_group_upgrade(installed_environments) ++ ++ with self.state as state: ++ state.download_status = 'downloading' ++ state.target_releasever = self.base.conf.releasever ++ state.destdir = self.base.conf.destdir ++ ++ def run_upgrade(self): ++ # change the upgrade status (so we can detect crashed upgrades later) ++ command = '' ++ with self.state as state: ++ state.upgrade_status = 'incomplete' ++ command = state.upgrade_command ++ if command == 'offline-upgrade': ++ msg = _("Starting offline upgrade. This will take a while.") ++ elif command == 'offline-distrosync': ++ msg = _("Starting offline distrosync. This will take a while.") ++ else: ++ msg = _("Starting system upgrade. This will take a while.") ++ ++ self.log_status(msg, UPGRADE_STARTED_ID) ++ ++ # reset the splash mode and let the user know we're running ++ Plymouth.set_mode() ++ Plymouth.progress(0) ++ Plymouth.message(msg) ++ ++ # disable screen blanking ++ disable_blanking() ++ ++ self.replay = TransactionReplay(self.base, self.transaction_file) ++ self.replay.run() ++ ++ def run_clean(self): ++ logger.info(_("Cleaning up downloaded data...")) ++ # Don't delete persistor, it contains paths for downloaded packages ++ # that are used by dnf during finalizing base to clean them up ++ clear_dir(self.base.conf.cachedir, ++ [dnf.persistor.TempfilePersistor(self.base.conf.cachedir).db_path]) ++ with self.state as state: ++ state.download_status = None ++ state.state_version = None ++ state.upgrade_status = None ++ state.upgrade_command = None ++ state.destdir = None ++ ++ def run_log(self): ++ if self.opts.number: ++ show_log(self.opts.number) ++ else: ++ list_logs() ++ ++ # == resolved_*: do staff after succesful resolvement ===================== ++ ++ def resolved_upgrade(self): ++ """Adjust transaction reasons according to stored values""" ++ self.replay.post_transaction() ++ ++ # == transaction_*: do stuff after a successful transaction =============== ++ ++ def transaction_download(self): ++ transaction = self.base.history.get_current() ++ ++ if not transaction.packages(): ++ logger.info(_("The system-upgrade transaction is empty, your system is already up-to-date.")) ++ return ++ ++ data = serialize_transaction(transaction) ++ try: ++ with open(self.transaction_file, "w") as f: ++ json.dump(data, f, indent=4, sort_keys=True) ++ f.write("\n") ++ ++ print(_("Transaction saved to {}.").format(self.transaction_file)) ++ ++ except OSError as e: ++ raise dnf.cli.CliError(_('Error storing transaction: {}').format(str(e))) ++ ++ # Okay! Write out the state so the upgrade can use it. ++ system_ver = dnf.rpm.detect_releasever(self.base.conf.installroot) ++ with self.state as state: ++ state.download_status = 'complete' ++ state.state_version = STATE_VERSION ++ state.distro_sync = self.opts.distro_sync ++ state.gpgcheck = self.base.conf.gpgcheck ++ state.gpgcheck_repos = [ ++ repo.id for repo in self.base.repos.values() if repo.gpgcheck] ++ state.repo_gpgcheck_repos = [ ++ repo.id for repo in self.base.repos.values() if repo.repo_gpgcheck] ++ state.system_releasever = system_ver ++ state.target_releasever = self.base.conf.releasever ++ state.module_platform_id = self.base.conf.module_platform_id ++ state.enable_disable_repos = self.opts.repos_ed ++ state.destdir = self.base.conf.destdir ++ state.upgrade_command = self.opts.command ++ ++ msg = DOWNLOAD_FINISHED_MSG.format(command=self.opts.command) ++ logger.info(msg) ++ self.log_status(_("Download finished."), DOWNLOAD_FINISHED_ID) ++ ++ def transaction_upgrade(self): ++ Plymouth.message(_("Upgrade complete! Cleaning up and rebooting...")) ++ self.log_status(_("Upgrade complete! Cleaning up and rebooting..."), ++ UPGRADE_FINISHED_ID) ++ self.run_clean() ++ if self.opts.tid[0] == "upgrade": ++ reboot() ++ ++ ++class OfflineUpgradeCommand(SystemUpgradeCommand): ++ aliases = ('offline-upgrade',) ++ summary = _("Prepare offline upgrade of the system") ++ ++ ++class OfflineDistrosyncCommand(SystemUpgradeCommand): ++ aliases = ('offline-distrosync',) ++ summary = _("Prepare offline distrosync of the system") +diff --git a/tests/test_system_upgrade.py b/tests/test_system_upgrade.py +new file mode 100644 +index 0000000..6ef4c21 +--- /dev/null ++++ b/tests/test_system_upgrade.py +@@ -0,0 +1,502 @@ ++# test_system_upgrade.py - unit tests for system-upgrade plugin ++ ++import system_upgrade ++ ++from system_upgrade import PLYMOUTH, CliError ++ ++import os ++import tempfile ++import shutil ++import gettext ++ ++from dnf.callback import (PKG_CLEANUP, PKG_DOWNGRADE, PKG_INSTALL, ++ PKG_OBSOLETE, PKG_REINSTALL, PKG_REMOVE, PKG_UPGRADE, ++ PKG_VERIFY, TRANS_POST) ++ ++import unittest ++ ++from tests.support import mock ++patch = mock.patch ++ ++ ++@patch('system_upgrade.call', return_value=0) ++class PlymouthTestCase(unittest.TestCase): ++ def setUp(self): ++ self.ply = system_upgrade.PlymouthOutput() ++ self.msg = "Hello, plymouth." ++ self.msg_args = (PLYMOUTH, "display-message", "--text", self.msg) ++ ++ def test_ping(self, call): ++ self.ply.ping() ++ call.assert_called_once_with((PLYMOUTH, "--ping")) ++ self.assertTrue(self.ply.alive) ++ ++ def test_ping_when_dead(self, call): ++ call.return_value = 1 ++ self.ply.ping() ++ self.assertFalse(self.ply.alive) ++ call.return_value = 0 ++ self.ply.ping() ++ self.assertEqual(call.call_count, 2) ++ self.assertTrue(self.ply.alive) ++ ++ def test_message(self, call): ++ self.ply.message(self.msg) ++ call.assert_called_once_with(self.msg_args) ++ ++ def test_hide_message(self, call): ++ messages = ("first", "middle", "BONUS", "last") ++ for m in messages: ++ self.ply.message(m) ++ ++ def hidem(m): ++ return mock.call((PLYMOUTH, "hide-message", "--text", m)) ++ ++ def dispm(m): ++ return mock.call((PLYMOUTH, "display-message", "--text", m)) ++ m1, m2, m3, m4 = messages ++ call.assert_has_calls([ ++ dispm(m1), ++ hidem(m1), dispm(m2), ++ hidem(m2), dispm(m3), ++ hidem(m3), dispm(m4), ++ ]) ++ ++ def test_message_dupe(self, call): ++ self.ply.message(self.msg) ++ self.ply.message(self.msg) ++ call.assert_called_once_with(self.msg_args) ++ ++ def test_message_dead(self, call): ++ call.return_value = 1 ++ self.ply.message(self.msg) ++ self.assertFalse(self.ply.alive) ++ self.ply.message("not even gonna bother") ++ call.assert_called_once_with(self.msg_args) ++ ++ def test_progress(self, call): ++ self.ply.progress(27) ++ call.assert_called_once_with( ++ (PLYMOUTH, "system-update", "--progress", str(27))) ++ ++ @patch('system_upgrade.check_output', ++ return_value="this plymouth does support --system-upgrade mode") ++ def test_mode(self, check_output, call): ++ self.ply.set_mode() ++ call.assert_called_once_with((PLYMOUTH, "change-mode", "--system-upgrade")) ++ ++ @patch('system_upgrade.check_output', ++ return_value="this plymouth doesn't support system-upgrade mode") ++ def test_mode_no_system_upgrade_plymouth(self, check_output, call): ++ self.ply.set_mode() ++ call.assert_called_once_with((PLYMOUTH, "change-mode", "--updates")) ++ ++ def test_mode_no_plymouth(self, call): ++ call.side_effect = OSError(2, 'No such file or directory') ++ self.ply.set_mode() ++ self.assertFalse(self.ply.alive) ++ ++ ++@patch('system_upgrade.call', return_value=0) ++class PlymouthTransactionProgressTestCase(unittest.TestCase): ++ actions = (PKG_CLEANUP, PKG_DOWNGRADE, PKG_INSTALL, PKG_OBSOLETE, ++ PKG_REINSTALL, PKG_REMOVE, PKG_UPGRADE, PKG_VERIFY, ++ TRANS_POST) ++ ++ # pylint: disable=protected-access ++ def setUp(self): ++ system_upgrade.Plymouth = system_upgrade.PlymouthOutput() ++ self.display = system_upgrade.PlymouthTransactionProgress() ++ self.pkg = "testpackage" ++ ++ def test_display(self, call): ++ for action in self.actions: ++ self.display.progress(self.pkg, action, 0, 100, 1, 1000) ++ msg = self.display._fmt_event(self.pkg, action, 1, 1000) ++ # updating plymouth display means two plymouth calls ++ call.assert_has_calls([ ++ mock.call((PLYMOUTH, "system-update", "--progress", "0")), ++ mock.call((PLYMOUTH, "display-message", "--text", msg)) ++ ], any_order=True) ++ ++ def test_filter_calls(self, call): ++ action = PKG_INSTALL ++ # first display update -> set percentage and text ++ self.display.progress(self.pkg, action, 0, 100, 1, 1000) ++ msg1 = self.display._fmt_event(self.pkg, action, 1, 1000) ++ call.assert_has_calls([ ++ mock.call((PLYMOUTH, "system-update", "--progress", "0")), ++ mock.call((PLYMOUTH, "display-message", "--text", msg1)), ++ ]) ++ ++ # event progress on the same transaction item. ++ # no new calls to plymouth because the percentage and text don't change ++ for te_cur in range(1, 100): ++ self.display.progress(self.pkg, action, te_cur, 100, 1, 1000) ++ call.assert_has_calls([ ++ mock.call((PLYMOUTH, "system-update", "--progress", "0")), ++ mock.call((PLYMOUTH, "display-message", "--text", msg1)), ++ ]) ++ ++ # new item: new message ("[2/1000] ..."), but percentage still 0.. ++ self.display.progress(self.pkg, action, 0, 100, 2, 1000) ++ # old message hidden, new message displayed. no new percentage. ++ msg2 = self.display._fmt_event(self.pkg, action, 2, 1000) ++ call.assert_has_calls([ ++ mock.call((PLYMOUTH, "system-update", "--progress", "0")), ++ mock.call((PLYMOUTH, "display-message", "--text", msg1)), ++ mock.call((PLYMOUTH, "hide-message", "--text", msg1)), ++ mock.call((PLYMOUTH, "display-message", "--text", msg2)), ++ ]) ++ ++ ++TESTLANG = "zh_CN" ++TESTLANG_MO = "po/%s.mo" % TESTLANG ++ ++ ++@unittest.skipUnless(os.path.exists(TESTLANG_MO), "make %s first" % ++ TESTLANG_MO) ++# @unittest.skip("There is no translation yet to system-upgrade") ++class I18NTestCaseBase(unittest.TestCase): ++ @classmethod ++ @unittest.skip("There is no translation yet to system-upgrade") ++ def setUpClass(cls): ++ cls.localedir = tempfile.mkdtemp(prefix='system_upgrade_test_i18n-') ++ cls.msgdir = os.path.join(cls.localedir, TESTLANG + "/LC_MESSAGES") ++ cls.msgfile = "dnf-plugins-extras" + ".mo" ++ os.makedirs(cls.msgdir) ++ shutil.copy2(TESTLANG_MO, os.path.join(cls.msgdir, cls.msgfile)) ++ ++ @classmethod ++ def tearDownClass(cls): ++ shutil.rmtree(cls.localedir) ++ ++ def setUp(self): ++ self.t = gettext.translation("dnf-plugins-extras", self.localedir, ++ languages=[TESTLANG], fallback=True) ++ self.gettext = self.t.gettext ++ ++ ++class I18NTestCase(I18NTestCaseBase): ++ @unittest.skip("There is no translation yet to system-upgrade") ++ def test_selftest(self): ++ self.assertIn(self.msgfile, os.listdir(self.msgdir)) ++ self.assertIn(TESTLANG, os.listdir(self.localedir)) ++ t = gettext.translation("dnf-plugins-extras", self.localedir, ++ languages=[TESTLANG], fallback=False) ++ info = t.info() ++ self.assertIn("language", info) ++ self.assertEqual(info["language"], TESTLANG.replace("_", "-")) ++ ++ @unittest.skip("There is no translation yet to system-upgrade") ++ def test_fallback(self): ++ msg = "THIS STRING DOES NOT EXIST" ++ trans_msg = self.gettext(msg) ++ self.assertEqual(msg, trans_msg) ++ ++ @unittest.skip("There is no translation yet to system-upgrade") ++ def test_translation(self): ++ msg = "the color of the sky" ++ trans_msg = self.gettext(msg) ++ self.assertNotEqual(msg, trans_msg) ++ ++ ++class StateTestCase(unittest.TestCase): ++ @classmethod ++ def setUpClass(cls): ++ cls.statedir = tempfile.mkdtemp(prefix="system_upgrade_test_state-") ++ cls.StateClass = system_upgrade.State ++ ++ def setUp(self): ++ self.state = self.StateClass(os.path.join(self.statedir, "state")) ++ ++ def test_bool_value(self): ++ with self.state: ++ self.state.distro_sync = True ++ del self.state ++ self.state = self.StateClass(os.path.join(self.statedir, "state")) ++ self.assertIs(self.state.distro_sync, True) ++ ++ @classmethod ++ def tearDownClass(cls): ++ shutil.rmtree(cls.statedir) ++ ++ ++class UtilTestCase(unittest.TestCase): ++ def setUp(self): ++ self.tmpdir = tempfile.mkdtemp(prefix='system_upgrade_test_util-') ++ self.dirs = ["dir1", "dir2"] ++ self.files = ["file1", "dir2/file2"] ++ for d in self.dirs: ++ os.makedirs(os.path.join(self.tmpdir, d)) ++ for f in self.files: ++ with open(os.path.join(self.tmpdir, f), 'wt') as fobj: ++ fobj.write("hi there\n") ++ ++ def test_self_test(self): ++ for d in self.dirs: ++ self.assertTrue(os.path.isdir(os.path.join(self.tmpdir, d))) ++ for f in self.files: ++ self.assertTrue(os.path.exists(os.path.join(self.tmpdir, f))) ++ ++ def test_clear_dir(self): ++ self.assertTrue(os.path.isdir(self.tmpdir)) ++ system_upgrade.clear_dir(self.tmpdir) ++ self.assertTrue(os.path.isdir(self.tmpdir)) ++ self.assertEqual(os.listdir(self.tmpdir), []) ++ ++ def tearDown(self): ++ shutil.rmtree(self.tmpdir) ++ ++ ++class CommandTestCaseBase(unittest.TestCase): ++ def setUp(self): ++ self.datadir = tempfile.mkdtemp(prefix="system_upgrade_test_datadir-") ++ self.installroot = tempfile.TemporaryDirectory(prefix="system_upgrade_test_installroot-") ++ system_upgrade.SystemUpgradeCommand.DATADIR = self.datadir ++ self.cli = mock.MagicMock() ++ # the installroot is not strictly necessary for the test, but ++ # releasever detection is accessing host system files without it, and ++ # this fails on permissions in COPR srpm builds (e.g. from rpm-gitoverlay) ++ self.cli.base.conf.installroot = self.installroot.name ++ self.command = system_upgrade.SystemUpgradeCommand(cli=self.cli) ++ self.command.base.conf.cachedir = os.path.join(self.datadir, "cache") ++ self.command.base.conf.destdir = None ++ ++ def tearDown(self): ++ shutil.rmtree(self.datadir) ++ self.installroot.cleanup() ++ ++ ++class CommandTestCase(CommandTestCaseBase): ++ # self-tests for the command test cases ++ def test_state(self): ++ # initial state: no status ++ self.assertIsNone(self.command.state.download_status) ++ self.assertIsNone(self.command.state.upgrade_status) ++ ++ ++class CleanCommandTestCase(CommandTestCaseBase): ++ def test_pre_configure_clean(self): ++ with self.command.state as state: ++ state.destdir = "/grape/wine" ++ self.command.pre_configure_clean() ++ self.assertEqual(self.command.base.conf.destdir, "/grape/wine") ++ ++ def test_configure_clean(self): ++ self.cli.demands.root_user = None ++ self.command.configure_clean() ++ self.assertTrue(self.cli.demands.root_user) ++ ++ def test_run_clean(self): ++ with self.command.state as state: ++ state.download_status = "complete" ++ state.upgrade_status = "ready" ++ # make sure the datadir and state info is set up OK ++ self.assertEqual(self.command.state.download_status, "complete") ++ self.assertEqual(self.command.state.upgrade_status, "ready") ++ # run cleanup ++ self.command.run_clean() ++ # state is cleared ++ self.assertIsNone(self.command.state.download_status) ++ self.assertIsNone(self.command.state.upgrade_status) ++ ++ ++class RebootCheckCommandTestCase(CommandTestCaseBase): ++ def setUp(self): ++ super(RebootCheckCommandTestCase, self).setUp() ++ self.magic_symlink = self.datadir + '/symlink' ++ self.command.magic_symlink = self.magic_symlink ++ ++ def test_pre_configure_reboot(self): ++ with self.command.state as state: ++ state.destdir = "/grape/wine" ++ self.command.pre_configure_reboot() ++ self.assertEqual(self.command.base.conf.destdir, "/grape/wine") ++ ++ def test_configure_reboot(self): ++ self.cli.demands.root_user = None ++ self.command.configure_reboot() ++ self.assertTrue(self.cli.demands.root_user) ++ ++ def check_reboot(self, status='complete', lexists=False, command='system-upgrade', ++ state_command='system-upgrade'): ++ with patch('system_upgrade.os.path.lexists') as lexists_func: ++ self.command.state.state_version = 2 ++ self.command.state.download_status = status ++ self.command.opts = mock.MagicMock() ++ self.command.opts.command = command ++ self.command.state.upgrade_command = state_command ++ lexists_func.return_value = lexists ++ self.command.check_reboot() ++ ++ def test_check_reboot_ok(self): ++ self.check_reboot(status='complete', lexists=False) ++ ++ def test_check_reboot_different_command(self): ++ with self.assertRaises(CliError): ++ self.check_reboot(status='complete', lexists=False, command='system-upgrade', ++ state_command='offline-upgrade') ++ ++ def test_check_reboot_no_download(self): ++ with self.assertRaises(CliError): ++ self.check_reboot(status=None, lexists=False) ++ ++ def test_check_reboot_link_exists(self): ++ with self.assertRaises(CliError): ++ self.check_reboot(status='complete', lexists=True) ++ ++ def test_run_prepare(self): ++ self.command.run_prepare() ++ self.assertEqual(os.readlink(self.magic_symlink), self.datadir) ++ self.assertEqual(self.command.state.upgrade_status, 'ready') ++ ++ @patch('system_upgrade.SystemUpgradeCommand.run_prepare') ++ @patch('system_upgrade.SystemUpgradeCommand.log_status') ++ @patch('system_upgrade.reboot') ++ def test_run_reboot(self, reboot, log_status, run_prepare): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.tid = ["reboot"] ++ self.command.run_reboot() ++ run_prepare.assert_called_once_with() ++ self.assertEqual(system_upgrade.REBOOT_REQUESTED_ID, ++ log_status.call_args[0][1]) ++ self.assertTrue(reboot.called) ++ ++ @patch('system_upgrade.SystemUpgradeCommand.run_prepare') ++ @patch('system_upgrade.SystemUpgradeCommand.log_status') ++ @patch('system_upgrade.reboot') ++ def test_reboot_prepare_only(self, reboot, log_status, run_prepare): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.tid = [None] ++ self.command.run_reboot() ++ run_prepare.assert_called_once_with() ++ self.assertFalse(log_status.called) ++ self.assertFalse(reboot.called) ++ ++ ++class DownloadCommandTestCase(CommandTestCase): ++ def test_pre_configure_download_default(self): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.destdir = None ++ self.command.base.conf.destdir = None ++ self.command.pre_configure_download() ++ self.assertEqual(self.command.base.conf.cachedir, self.datadir) ++ ++ def test_pre_configure_download_destdir(self): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.destdir = self.datadir ++ self.command.pre_configure_download() ++ self.assertEqual(self.command.base.conf.destdir, self.datadir) ++ ++ def test_configure_download(self): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.tid = "download" ++ self.command.configure() ++ self.assertTrue(self.cli.demands.root_user) ++ self.assertTrue(self.cli.demands.resolving) ++ self.assertTrue(self.cli.demands.sack_activation) ++ self.assertTrue(self.cli.demands.available_repos) ++ ++ def test_transaction_download(self): ++ pkg = mock.MagicMock() ++ repo = mock.MagicMock() ++ repo.id = 'test' ++ pkg.name = "kernel" ++ pkg.repo = repo ++ self.cli.base.transaction.install_set = [pkg] ++ self.command.opts = mock.MagicMock() ++ self.command.opts.distro_sync = True ++ self.command.opts.command = "system_upgrade" ++ self.command.opts.repos_ed = [] ++ self.cli.demands.allow_erasing = "allow_erasing" ++ self.command.base.conf.best = True ++ self.command.base.conf.releasever = "35" ++ self.command.base.conf.gpgcheck = True ++ self.command.opts.destdir = self.datadir ++ self.command.base.conf.install_weak_deps = True ++ self.command.base.conf.module_platform_id = '' ++ self.command.pre_configure_download() ++ self.command.transaction_download() ++ with system_upgrade.State(self.command.state.statefile) as state: ++ self.assertEqual(state.state_version, system_upgrade.STATE_VERSION) ++ self.assertEqual(state.download_status, "complete") ++ self.assertEqual(state.distro_sync, True) ++ self.assertEqual(state.destdir, self.datadir) ++ self.assertEqual(state.upgrade_command, "system_upgrade") ++ ++ def test_transaction_download_offline_upgrade(self): ++ pkg = mock.MagicMock() ++ repo = mock.MagicMock() ++ repo.id = 'test' ++ pkg.name = "kernel" ++ pkg.repo = repo ++ self.cli.base.transaction.install_set = [pkg] ++ self.command.opts = mock.MagicMock() ++ self.command.opts.distro_sync = True ++ self.command.opts.command = "offline-upgrade" ++ self.command.opts.repos_ed = [] ++ self.cli.demands.allow_erasing = "allow_erasing" ++ self.command.base.conf.best = True ++ self.command.base.conf.releasever = "35" ++ self.command.base.conf.gpgcheck = True ++ self.command.opts.destdir = self.datadir ++ self.command.base.conf.install_weak_deps = True ++ self.command.base.conf.module_platform_id = '' ++ self.command.pre_configure_download() ++ self.command.transaction_download() ++ with system_upgrade.State(self.command.state.statefile) as state: ++ self.assertEqual(state.download_status, "complete") ++ self.assertEqual(state.distro_sync, False) ++ self.assertEqual(state.destdir, self.datadir) ++ self.assertEqual(state.upgrade_command, "offline-upgrade") ++ ++ ++class UpgradeCommandTestCase(CommandTestCase): ++ def test_pre_configure_upgrade(self): ++ with self.command.state as state: ++ state.destdir = "/grape/wine" ++ state.target_releasever = "35" ++ self.command.pre_configure_upgrade() ++ self.assertEqual(self.command.base.conf.destdir, "/grape/wine") ++ self.assertEqual(self.command.base.conf.releasever, "35") ++ ++ def test_configure_upgrade(self): ++ # write state like download would have ++ with self.command.state as state: ++ state.download_status = "complete" ++ state.distro_sync = True ++ state.allow_erasing = True ++ state.best = True ++ # okay, now configure upgrade ++ self.command.opts = mock.MagicMock() ++ self.command.opts.tid = "upgrade" ++ self.command.configure() ++ # did we reset the depsolving flags? ++ self.assertTrue(self.command.opts.distro_sync) ++ self.assertTrue(self.cli.demands.allow_erasing) ++ self.assertTrue(self.command.base.conf.best) ++ # are we on autopilot? ++ self.assertTrue(self.command.base.conf.assumeyes) ++ self.assertTrue(self.cli.demands.cacheonly) ++ ++ ++class LogCommandTestCase(CommandTestCase): ++ def test_configure_log(self): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.tid = "log" ++ self.command.configure() ++ ++ def test_run_log_list(self): ++ self.command.opts = mock.MagicMock() ++ self.command.opts.number = None ++ with patch('system_upgrade.list_logs') as list_logs: ++ self.command.run_log() ++ list_logs.assert_called_once_with() ++ ++ def test_run_log_prev(self): ++ with patch('system_upgrade.show_log') as show_log: ++ self.command.opts = mock.MagicMock() ++ self.command.opts.number = -2 ++ self.command.run_log() ++ show_log.assert_called_once_with(-2) +-- +2.37.3 + diff --git a/SOURCES/0026-Add-a-warning-when-using-system-upgrade-on-RHEL.patch b/SOURCES/0026-Add-a-warning-when-using-system-upgrade-on-RHEL.patch new file mode 100644 index 0000000..1bac21b --- /dev/null +++ b/SOURCES/0026-Add-a-warning-when-using-system-upgrade-on-RHEL.patch @@ -0,0 +1,78 @@ +From e52655aa9c7c9ad334639990d612da574b57736b Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +Date: Fri, 30 Sep 2022 11:36:26 +0000 +Subject: [PATCH 1/3] Add a warning when using `system-upgrade` on RHEL + +--- + dnf-plugins-core.spec | 3 +-- + doc/system-upgrade.rst | 6 ++++-- + plugins/system_upgrade.py | 4 ++++ + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec +index 0e1c9e3..a5ec165 100644 +--- a/dnf-plugins-core.spec ++++ b/dnf-plugins-core.spec +@@ -148,14 +148,13 @@ Summary: Core Plugins for DNF + %{?python_provide:%python_provide python3-%{name}} + BuildRequires: python3-dbus + BuildRequires: python3-devel ++BuildRequires: python3-distro + BuildRequires: python3-dnf >= %{dnf_lowest_compatible} + BuildRequires: python3-systemd + BuildRequires: pkgconfig(systemd) + BuildRequires: systemd + %{?systemd_ordering} +-%if 0%{?fedora} + Requires: python3-distro +-%endif + Requires: python3-dbus + Requires: python3-dnf >= %{dnf_lowest_compatible} + Requires: python3-hawkey >= %{hawkey_version} +diff --git a/doc/system-upgrade.rst b/doc/system-upgrade.rst +index 3110460..87b7319 100644 +--- a/doc/system-upgrade.rst ++++ b/doc/system-upgrade.rst +@@ -27,13 +27,15 @@ DNF system-upgrades plugin provides three commands: ``system-upgrade``, ``offlin + ``offline-distrosync``. Only ``system-upgrade`` command requires increase of distribution major + version (``--releasever``) compared to installed version. + +-``dnf system-upgrade`` can be used to upgrade a Fedora system to a new major +-release. It replaces fedup (the old Fedora Upgrade tool). Before you proceed ensure that your system ++``dnf system-upgrade`` is a recommended way to upgrade a system to a new major release. ++It replaces fedup (the old Fedora Upgrade tool). Before you proceed ensure that your system + is fully upgraded (``dnf --refresh upgrade``). + + The ``system-upgrade`` command also performes additional actions necessary for the upgrade of the + system, for example an upgrade of groups and environments. + ++.. WARNING:: The ``system-upgrade`` command is not supported on the RHEL distribution. ++ + -------- + Synopsis + -------- +diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py +index fee6762..0baf978 100644 +--- a/plugins/system_upgrade.py ++++ b/plugins/system_upgrade.py +@@ -20,6 +20,7 @@ + """system_upgrade.py - DNF plugin to handle major-version system upgrades.""" + + from subprocess import call, Popen, check_output, CalledProcessError ++import distro + import json + import os + import os.path +@@ -451,6 +452,9 @@ class SystemUpgradeCommand(dnf.cli.Command): + + def configure_download(self): + if 'system-upgrade' == self.opts.command or 'fedup' == self.opts.command: ++ if distro.id() == 'rhel': ++ logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. ' ++ 'Proceed at your own risk.')) + help_url = get_url_from_os_release() + if help_url: + msg = _('Additional information for System Upgrade: {}') +-- +2.38.1 + diff --git a/SOURCES/0027-offline-upgrade-Add-security-filters.patch b/SOURCES/0027-offline-upgrade-Add-security-filters.patch new file mode 100644 index 0000000..339d81f --- /dev/null +++ b/SOURCES/0027-offline-upgrade-Add-security-filters.patch @@ -0,0 +1,61 @@ +From 3a18b7241708a3c5fd1b4b92a2f9908a826e815d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tarc=C3=ADsio=20Ladeia=20de=20Oliveira?= + +Date: Thu, 20 Oct 2022 22:16:59 -0300 +Subject: [PATCH 1/2] [offline-upgrade] Add security filters (RhBug:1939975) + +Add support for security filter options that are available in the main +`dnf` commands, that is, `--advisory`, `--bugfix`, `--security`, and +`--enhancement`. + += changelog = +msg: [offline-upgrade] Add support for security filters +type: bugfix +resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1939975 +--- + plugins/system_upgrade.py | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py +index 0baf978..ef1de73 100644 +--- a/plugins/system_upgrade.py ++++ b/plugins/system_upgrade.py +@@ -467,6 +467,9 @@ class SystemUpgradeCommand(dnf.cli.Command): + logger.error(_("Operation aborted.")) + sys.exit(1) + check_release_ver(self.base.conf, target=self.opts.releasever) ++ elif 'offline-upgrade' == self.opts.command: ++ self.cli._populate_update_security_filter(self.opts) ++ + self.cli.demands.root_user = True + self.cli.demands.resolving = True + self.cli.demands.available_repos = True +-- +2.38.1 + + +From dad20a478e100bd0ac3a8d7d51dad75baca90c7f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tarc=C3=ADsio=20Ladeia=20de=20Oliveira?= + +Date: Thu, 20 Oct 2022 22:27:22 -0300 +Subject: [PATCH 2/2] Add myself as contributor in AUTHORS + +--- + AUTHORS | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/AUTHORS b/AUTHORS +index 33512fd..cd4b5be 100644 +--- a/AUTHORS ++++ b/AUTHORS +@@ -32,6 +32,7 @@ DNF-PLUGINS-CORE CONTRIBUTORS + Neal Gompa + Paul Howarth + Rickard Dybeck ++ Tarcísio Ladeia de Oliveira + Tomas Babej + Vladan Kudlac + Wieland Hoffmann +-- +2.38.1 + diff --git a/SOURCES/0028-system-upgrade-Show-warning-always-for-a-downstream.patch b/SOURCES/0028-system-upgrade-Show-warning-always-for-a-downstream.patch new file mode 100644 index 0000000..03999e3 --- /dev/null +++ b/SOURCES/0028-system-upgrade-Show-warning-always-for-a-downstream.patch @@ -0,0 +1,62 @@ +From dfbda502c5c46daf84e00179478de01e452f9dae Mon Sep 17 00:00:00 2001 +From: Jan Kolarik +Date: Fri, 16 Dec 2022 05:55:19 +0000 +Subject: [PATCH] system-upgrade: Show warning always for a downstream + +As the distro package is not available in the BaseOS, the warning implementation will be shown always, but only in related downstreams. + += changelog = +type: bugfix +resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2152846 +--- + dnf-plugins-core.spec | 3 ++- + plugins/system_upgrade.py | 6 ++---- + 2 files changed, 4 insertions(+), 5 deletions(-) + +diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec +index a5ec165..0e1c9e3 100644 +--- a/dnf-plugins-core.spec ++++ b/dnf-plugins-core.spec +@@ -148,13 +148,14 @@ Summary: Core Plugins for DNF + %{?python_provide:%python_provide python3-%{name}} + BuildRequires: python3-dbus + BuildRequires: python3-devel +-BuildRequires: python3-distro + BuildRequires: python3-dnf >= %{dnf_lowest_compatible} + BuildRequires: python3-systemd + BuildRequires: pkgconfig(systemd) + BuildRequires: systemd + %{?systemd_ordering} ++%if 0%{?fedora} + Requires: python3-distro ++%endif + Requires: python3-dbus + Requires: python3-dnf >= %{dnf_lowest_compatible} + Requires: python3-hawkey >= %{hawkey_version} +diff --git a/plugins/system_upgrade.py b/plugins/system_upgrade.py +index ef1de73..4f7620f 100644 +--- a/plugins/system_upgrade.py ++++ b/plugins/system_upgrade.py +@@ -20,7 +20,6 @@ + """system_upgrade.py - DNF plugin to handle major-version system upgrades.""" + + from subprocess import call, Popen, check_output, CalledProcessError +-import distro + import json + import os + import os.path +@@ -452,9 +451,8 @@ class SystemUpgradeCommand(dnf.cli.Command): + + def configure_download(self): + if 'system-upgrade' == self.opts.command or 'fedup' == self.opts.command: +- if distro.id() == 'rhel': +- logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. ' +- 'Proceed at your own risk.')) ++ logger.warning(_('WARNING: this operation is not supported on the RHEL distribution. ' ++ 'Proceed at your own risk.')) + help_url = get_url_from_os_release() + if help_url: + msg = _('Additional information for System Upgrade: {}') +-- +2.39.0 + diff --git a/SOURCES/0029-Update-translations.patch b/SOURCES/0029-Update-translations.patch new file mode 100644 index 0000000..08781e6 --- /dev/null +++ b/SOURCES/0029-Update-translations.patch @@ -0,0 +1,3803 @@ +From ad97fc64d718ab5aed5e44608a761f2eaf1050f7 Mon Sep 17 00:00:00 2001 +From: Marek Blaha +Date: Wed, 8 Mar 2023 11:22:51 +0100 +Subject: [PATCH] Update translations + +--- + po/dnf-plugins-core.pot | 343 ++++++++++++++++++++----- + po/fr.po | 399 +++++++++++++++++++++++------ + po/ja.po | 417 +++++++++++++++++++++++------- + po/ko.po | 548 ++++++++++++++++++++++++++++------------ + po/zh_CN.po | 388 ++++++++++++++++++++++------ + 5 files changed, 1642 insertions(+), 453 deletions(-) + +diff --git a/po/dnf-plugins-core.pot b/po/dnf-plugins-core.pot +index 3ec9a50..aba1e70 100644 +--- a/po/dnf-plugins-core.pot ++++ b/po/dnf-plugins-core.pot +@@ -8,7 +8,7 @@ msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2022-02-28 11:53+0100\n" ++"POT-Creation-Date: 2023-02-28 12:21+0100\n" + "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" + "Last-Translator: FULL NAME \n" + "Language-Team: LANGUAGE \n" +@@ -67,16 +67,21 @@ msgstr "" + msgid "Failed to open: '%s', not a valid source rpm file." + msgstr "" + +-#: plugins/builddep.py:204 plugins/builddep.py:220 plugins/builddep.py:237 ++#: plugins/builddep.py:204 plugins/builddep.py:224 plugins/builddep.py:241 + msgid "Not all dependencies satisfied" + msgstr "" + +-#: plugins/builddep.py:211 ++#: plugins/builddep.py:208 ++msgid "" ++"Warning: -D or --define arguments have no meaning for source rpm packages." ++msgstr "" ++ ++#: plugins/builddep.py:215 + #, python-format + msgid "Failed to open: '%s', not a valid spec file: %s" + msgstr "" + +-#: plugins/builddep.py:230 plugins/repoclosure.py:118 ++#: plugins/builddep.py:234 plugins/repoclosure.py:118 + #, python-format + msgid "no package matched: %s" + msgstr "" +@@ -201,27 +206,27 @@ msgstr[1] "" + msgid "Could not save repo to repofile %s: %s" + msgstr "" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "y" + msgstr "" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "yes" + msgstr "" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "n" + msgstr "" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "no" + msgstr "" + +-#: plugins/copr.py:84 ++#: plugins/copr.py:92 + msgid "Interact with Copr repositories." + msgstr "" + +-#: plugins/copr.py:86 ++#: plugins/copr.py:94 + msgid "" + "\n" + " enable name/project [chroot]\n" +@@ -242,63 +247,63 @@ msgid "" + " " + msgstr "" + +-#: plugins/copr.py:112 ++#: plugins/copr.py:120 + msgid "List all installed Copr repositories (default)" + msgstr "" + +-#: plugins/copr.py:114 ++#: plugins/copr.py:122 + msgid "List enabled Copr repositories" + msgstr "" + +-#: plugins/copr.py:116 ++#: plugins/copr.py:124 + msgid "List disabled Copr repositories" + msgstr "" + +-#: plugins/copr.py:118 ++#: plugins/copr.py:126 + msgid "List available Copr repositories by user NAME" + msgstr "" + +-#: plugins/copr.py:120 ++#: plugins/copr.py:128 + msgid "Specify an instance of Copr to work with" + msgstr "" + +-#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 ++#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 + msgid "Error: " + msgstr "" + +-#: plugins/copr.py:155 ++#: plugins/copr.py:165 + msgid "" + "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" + "copr_projectname` format" + msgstr "" + +-#: plugins/copr.py:158 ++#: plugins/copr.py:168 + msgid "multiple hubs specified" + msgstr "" + +-#: plugins/copr.py:223 plugins/copr.py:227 ++#: plugins/copr.py:237 plugins/copr.py:241 + msgid "exactly two additional parameters to copr command are required" + msgstr "" + +-#: plugins/copr.py:232 ++#: plugins/copr.py:246 + msgid "Too many arguments." + msgstr "" + +-#: plugins/copr.py:235 ++#: plugins/copr.py:249 + msgid "" + "Bad format of optional chroot. The format is distribution-version-" + "architecture." + msgstr "" + +-#: plugins/copr.py:250 ++#: plugins/copr.py:264 + msgid "use format `copr_username/copr_projectname` to reference copr project" + msgstr "" + +-#: plugins/copr.py:252 ++#: plugins/copr.py:266 + msgid "bad copr project format" + msgstr "" + +-#: plugins/copr.py:266 ++#: plugins/copr.py:280 + msgid "" + "\n" + "Enabling a Copr repository. Please note that this repository is not part\n" +@@ -314,71 +319,102 @@ msgid "" + "Bugzilla. In case of problems, contact the owner of this repository.\n" + msgstr "" + +-#: plugins/copr.py:283 ++#: plugins/copr.py:297 + msgid "Repository successfully enabled." + msgstr "" + +-#: plugins/copr.py:288 ++#: plugins/copr.py:302 + msgid "Repository successfully disabled." + msgstr "" + +-#: plugins/copr.py:292 ++#: plugins/copr.py:306 + msgid "Repository successfully removed." + msgstr "" + +-#: plugins/copr.py:296 plugins/copr.py:697 ++#: plugins/copr.py:310 plugins/copr.py:721 + msgid "Unknown subcommand {}." + msgstr "" + +-#: plugins/copr.py:353 ++#: plugins/copr.py:367 + msgid "" + "* These coprs have repo file with an old format that contains no information " + "about Copr hub - the default one was assumed. Re-enable the project to fix " + "this." + msgstr "" + +-#: plugins/copr.py:366 ++#: plugins/copr.py:380 + msgid "Can't parse repositories for username '{}'." + msgstr "" + +-#: plugins/copr.py:369 ++#: plugins/copr.py:383 + msgid "List of {} coprs" + msgstr "" + +-#: plugins/copr.py:374 ++#: plugins/copr.py:388 + msgid "No description given" + msgstr "" + +-#: plugins/copr.py:386 ++#: plugins/copr.py:400 + msgid "Can't parse search for '{}'." + msgstr "" + +-#: plugins/copr.py:389 ++#: plugins/copr.py:403 + msgid "Matched: {}" + msgstr "" + +-#: plugins/copr.py:394 ++#: plugins/copr.py:408 + msgid "No description given." + msgstr "" + +-#: plugins/copr.py:416 ++#: plugins/copr.py:430 + msgid "Safe and good answer. Exiting." + msgstr "" + +-#: plugins/copr.py:423 ++#: plugins/copr.py:437 + msgid "This command has to be run under the root user." + msgstr "" + +-#: plugins/copr.py:485 ++#: plugins/copr.py:487 ++#, python-brace-format ++msgid "Request to {0} failed: {1} - {2}" ++msgstr "" ++ ++#: plugins/copr.py:489 ++msgid "It wasn't possible to enable this project.\n" ++msgstr "" ++ ++#: plugins/copr.py:494 ++#, python-brace-format ++msgid "Repository '{0}' does not exist in project '{1}'." ++msgstr "" ++ ++#: plugins/copr.py:497 + msgid "" +-"This repository does not have any builds yet so you cannot enable it now." ++"\n" ++"Available repositories: " ++msgstr "" ++ ++#: plugins/copr.py:499 ++#, python-brace-format ++msgid "" ++"\n" ++"\n" ++"If you want to enable a non-default repository, use the following command:\n" ++" 'dnf copr enable {0} '\n" ++"But note that the installed repo file will likely need a manual modification." + msgstr "" + +-#: plugins/copr.py:488 +-msgid "Such repository does not exist." ++#: plugins/copr.py:505 ++#, python-brace-format ++msgid "Project {0} does not exist." + msgstr "" + +-#: plugins/copr.py:532 ++#: plugins/copr.py:508 ++#, python-brace-format ++msgid "Failed to connect to {0}: {1}" ++msgstr "" ++ ++#: plugins/copr.py:555 + #, python-brace-format + msgid "" + "Maintainer of the enabled Copr repository decided to make\n" +@@ -395,44 +431,44 @@ msgid "" + "These repositories have been enabled automatically." + msgstr "" + +-#: plugins/copr.py:553 ++#: plugins/copr.py:576 + msgid "Do you want to keep them enabled?" + msgstr "" + +-#: plugins/copr.py:586 ++#: plugins/copr.py:609 + #, python-brace-format + msgid "Failed to remove copr repo {0}/{1}/{2}" + msgstr "" + +-#: plugins/copr.py:597 ++#: plugins/copr.py:620 + msgid "Failed to disable copr repo {}/{}" + msgstr "" + +-#: plugins/copr.py:615 plugins/copr.py:652 ++#: plugins/copr.py:638 plugins/copr.py:675 + msgid "Unknown response from server." + msgstr "" + +-#: plugins/copr.py:637 ++#: plugins/copr.py:660 + msgid "Interact with Playground repository." + msgstr "" + +-#: plugins/copr.py:643 ++#: plugins/copr.py:666 + msgid "Enabling a Playground repository." + msgstr "" + +-#: plugins/copr.py:644 ++#: plugins/copr.py:667 + msgid "Do you want to continue?" + msgstr "" + +-#: plugins/copr.py:687 ++#: plugins/copr.py:711 + msgid "Playground repositories successfully enabled." + msgstr "" + +-#: plugins/copr.py:690 ++#: plugins/copr.py:714 + msgid "Playground repositories successfully disabled." + msgstr "" + +-#: plugins/copr.py:694 ++#: plugins/copr.py:718 + msgid "Playground repositories successfully updated." + msgstr "" + +@@ -845,18 +881,18 @@ msgid "Bad Action Line \"%s\": %s" + msgstr "" + + #. unsupported state, skip it +-#: plugins/post-transaction-actions.py:130 ++#: plugins/post-transaction-actions.py:133 + #, python-format + msgid "Bad Transaction State: %s" + msgstr "" + +-#: plugins/post-transaction-actions.py:157 +-#: plugins/post-transaction-actions.py:159 ++#: plugins/post-transaction-actions.py:160 ++#: plugins/post-transaction-actions.py:162 + #, python-format + msgid "post-transaction-actions: %s" + msgstr "" + +-#: plugins/post-transaction-actions.py:161 ++#: plugins/post-transaction-actions.py:164 + #, python-format + msgid "post-transaction-actions: Bad Command \"%s\": %s" + msgstr "" +@@ -1027,31 +1063,43 @@ msgstr "" + msgid "Pass either --old or --new, not both!" + msgstr "" + +-#: plugins/repomanage.py:89 ++#: plugins/repomanage.py:61 ++msgid "Pass either --oldonly or --new, not both!" ++msgstr "" ++ ++#: plugins/repomanage.py:63 ++msgid "Pass either --old or --oldonly, not both!" ++msgstr "" ++ ++#: plugins/repomanage.py:100 + msgid "No files to process" + msgstr "" + +-#: plugins/repomanage.py:96 ++#: plugins/repomanage.py:107 + msgid "Could not open {}" + msgstr "" + +-#: plugins/repomanage.py:180 ++#: plugins/repomanage.py:223 + msgid "Print the older packages" + msgstr "" + +-#: plugins/repomanage.py:182 ++#: plugins/repomanage.py:225 ++msgid "Print the older packages. Exclude the newest packages." ++msgstr "" ++ ++#: plugins/repomanage.py:227 + msgid "Print the newest packages" + msgstr "" + +-#: plugins/repomanage.py:184 ++#: plugins/repomanage.py:229 + msgid "Space separated output, not newline" + msgstr "" + +-#: plugins/repomanage.py:186 ++#: plugins/repomanage.py:231 + msgid "Newest N packages to keep - defaults to 1" + msgstr "" + +-#: plugins/repomanage.py:189 ++#: plugins/repomanage.py:234 + msgid "Path to directory" + msgstr "" + +@@ -1153,6 +1201,175 @@ msgstr "" + msgid "New leaves:" + msgstr "" + ++#. Translators: This string is only used in unit tests. ++#: plugins/system_upgrade.py:45 ++msgid "the color of the sky" ++msgstr "" ++ ++#: plugins/system_upgrade.py:57 ++msgid "Need a --releasever greater than the current system version." ++msgstr "" ++ ++#. Translators: do not change "reboot" here ++#: plugins/system_upgrade.py:59 ++#, python-brace-format ++msgid "" ++"Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++"To remove cached metadata and transaction use 'dnf {command} clean'" ++msgstr "" ++ ++#: plugins/system_upgrade.py:62 ++msgid "Sorry, you need to use 'download --releasever' instead of '--network'" ++msgstr "" ++ ++#: plugins/system_upgrade.py:71 ++msgid "Reboot turned off, not rebooting." ++msgstr "" ++ ++#: plugins/system_upgrade.py:122 ++#, python-format ++msgid "Screen blanking can't be disabled: %s" ++msgstr "" ++ ++#: plugins/system_upgrade.py:142 ++#, python-format ++msgid "Failed loading state file: %s, continuing with empty state." ++msgstr "" ++ ++#: plugins/system_upgrade.py:289 ++msgid "The following boots appear to contain upgrade logs:" ++msgstr "" ++ ++#: plugins/system_upgrade.py:299 ++msgid "-- no logs were found --" ++msgstr "" ++ ++#: plugins/system_upgrade.py:314 ++msgid "Cannot find logs with this index." ++msgstr "" ++ ++#: plugins/system_upgrade.py:323 ++msgid "Unable to match systemd journal entry" ++msgstr "" ++ ++#: plugins/system_upgrade.py:344 ++msgid "Prepare system for upgrade to a new release" ++msgstr "" ++ ++#: plugins/system_upgrade.py:360 ++msgid "keep installed packages if the new release's version is older" ++msgstr "" ++ ++#: plugins/system_upgrade.py:364 ++msgid "which logs to show" ++msgstr "" ++ ++#: plugins/system_upgrade.py:398 ++#, python-brace-format ++msgid "Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++msgstr "" ++ ++#: plugins/system_upgrade.py:434 ++msgid "Command 'offline-distrosync' cannot be used with --no-downgrade option" ++msgstr "" ++ ++#: plugins/system_upgrade.py:454 ++msgid "" ++"WARNING: this operation is not supported on the RHEL distribution. Proceed " ++"at your own risk." ++msgstr "" ++ ++#: plugins/system_upgrade.py:458 ++msgid "Additional information for System Upgrade: {}" ++msgstr "" ++ ++#: plugins/system_upgrade.py:461 ++msgid "" ++"Before you continue ensure that your system is fully upgraded by running " ++"\"dnf --refresh upgrade\". Do you want to continue" ++msgstr "" ++ ++#: plugins/system_upgrade.py:465 ++msgid "Operation aborted." ++msgstr "" ++ ++#: plugins/system_upgrade.py:526 ++msgid "system is not ready for upgrade" ++msgstr "" ++ ++#: plugins/system_upgrade.py:529 ++#, python-brace-format ++msgid "" ++"the transaction was not prepared for '{command}'. Rerun 'dnf {command} " ++"download [OPTIONS]'" ++msgstr "" ++ ++#: plugins/system_upgrade.py:533 ++msgid "upgrade is already scheduled" ++msgstr "" ++ ++#: plugins/system_upgrade.py:539 ++msgid "trigger file does not exist. exiting quietly." ++msgstr "" ++ ++#: plugins/system_upgrade.py:542 ++msgid "another upgrade tool is running. exiting quietly." ++msgstr "" ++ ++#: plugins/system_upgrade.py:551 ++#, python-brace-format ++msgid "use 'dnf {command} reboot' to begin the upgrade" ++msgstr "" ++ ++#: plugins/system_upgrade.py:569 ++msgid "Rebooting to perform upgrade." ++msgstr "" ++ ++#: plugins/system_upgrade.py:602 ++msgid "Starting offline upgrade. This will take a while." ++msgstr "" ++ ++#: plugins/system_upgrade.py:604 ++msgid "Starting offline distrosync. This will take a while." ++msgstr "" ++ ++#: plugins/system_upgrade.py:606 ++msgid "Starting system upgrade. This will take a while." ++msgstr "" ++ ++#: plugins/system_upgrade.py:622 ++msgid "Cleaning up downloaded data..." ++msgstr "" ++ ++#: plugins/system_upgrade.py:652 ++msgid "" ++"The system-upgrade transaction is empty, your system is already up-to-date." ++msgstr "" ++ ++#: plugins/system_upgrade.py:661 ++msgid "Transaction saved to {}." ++msgstr "" ++ ++#: plugins/system_upgrade.py:664 ++msgid "Error storing transaction: {}" ++msgstr "" ++ ++#: plugins/system_upgrade.py:686 ++msgid "Download finished." ++msgstr "" ++ ++#: plugins/system_upgrade.py:689 plugins/system_upgrade.py:690 ++msgid "Upgrade complete! Cleaning up and rebooting..." ++msgstr "" ++ ++#: plugins/system_upgrade.py:699 ++msgid "Prepare offline upgrade of the system" ++msgstr "" ++ ++#: plugins/system_upgrade.py:704 ++msgid "Prepare offline distrosync of the system" ++msgstr "" ++ + #: plugins/versionlock.py:33 + #, python-format + msgid "Unable to read version lock configuration: %s" +diff --git a/po/fr.po b/po/fr.po +index f70bfb2..153eb56 100644 +--- a/po/fr.po ++++ b/po/fr.po +@@ -7,14 +7,15 @@ + # Jean-Baptiste Holcroft , 2019. #zanata, 2020. + # Julien Humbert , 2020. + # Sundeep Anand , 2021. +-# Transtats , 2022. ++# Transtats , 2022, 2023. ++# blutch112 , 2022. + msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2022-02-28 11:53+0100\n" +-"PO-Revision-Date: 2022-03-09 12:39+0000\n" +-"Last-Translator: Ludek Janda \n" ++"POT-Creation-Date: 2023-02-28 12:21+0100\n" ++"PO-Revision-Date: 2023-03-06 13:48+0000\n" ++"Last-Translator: Transtats \n" + "Language-Team: French \n" + "Language: fr\n" +@@ -22,7 +23,7 @@ msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=2; plural=n > 1;\n" +-"X-Generator: Weblate 4.11.2\n" ++"X-Generator: Weblate 4.15.2\n" + + #: plugins/builddep.py:45 + msgid "[PACKAGE|PACKAGE.spec]" +@@ -73,16 +74,23 @@ msgstr "Aucun paquet correspondant à installer : « %s »" + msgid "Failed to open: '%s', not a valid source rpm file." + msgstr "Échec d’ouverture : « %s », n’est pas un fichier source rpm valide." + +-#: plugins/builddep.py:204 plugins/builddep.py:220 plugins/builddep.py:237 ++#: plugins/builddep.py:204 plugins/builddep.py:224 plugins/builddep.py:241 + msgid "Not all dependencies satisfied" + msgstr "Toutes les dépendances ne sont pas satisfaites" + +-#: plugins/builddep.py:211 ++#: plugins/builddep.py:208 ++msgid "" ++"Warning: -D or --define arguments have no meaning for source rpm packages." ++msgstr "" ++"Attention : les arguments -D ou --define n'ont aucune signification pour les " ++"paquets rpm source." ++ ++#: plugins/builddep.py:215 + #, python-format + msgid "Failed to open: '%s', not a valid spec file: %s" + msgstr "Échec à l’ouverture de « %s », %s n’est pas un fichier spec valide" + +-#: plugins/builddep.py:230 plugins/repoclosure.py:118 ++#: plugins/builddep.py:234 plugins/repoclosure.py:118 + #, python-format + msgid "no package matched: %s" + msgstr "aucun paquet ne correspond à : %s" +@@ -219,27 +227,27 @@ msgstr[1] "La configuration des dépôts a échoué" + msgid "Could not save repo to repofile %s: %s" + msgstr "Sauvegarde impossible du dépôt dans le fichier du dépôt %s : %s" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "y" + msgstr "o" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "yes" + msgstr "oui" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "n" + msgstr "n" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "no" + msgstr "non" + +-#: plugins/copr.py:84 ++#: plugins/copr.py:92 + msgid "Interact with Copr repositories." + msgstr "Interagit avec les dépôts Copr." + +-#: plugins/copr.py:86 ++#: plugins/copr.py:94 + msgid "" + "\n" + " enable name/project [chroot]\n" +@@ -277,31 +285,31 @@ msgstr "" + " copr search tests\n" + " " + +-#: plugins/copr.py:112 ++#: plugins/copr.py:120 + msgid "List all installed Copr repositories (default)" + msgstr "Lister tous les dépôts Copr installés (par défaut)" + +-#: plugins/copr.py:114 ++#: plugins/copr.py:122 + msgid "List enabled Copr repositories" + msgstr "Lister les dépôts Copr activés" + +-#: plugins/copr.py:116 ++#: plugins/copr.py:124 + msgid "List disabled Copr repositories" + msgstr "Lister les dépôts Copr désactivés" + +-#: plugins/copr.py:118 ++#: plugins/copr.py:126 + msgid "List available Copr repositories by user NAME" + msgstr "Lister les dépôts Copr disponibles par NOM d’utilisateur" + +-#: plugins/copr.py:120 ++#: plugins/copr.py:128 + msgid "Specify an instance of Copr to work with" + msgstr "Précisez une instance Copr avec laquelle travailler" + +-#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 ++#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 + msgid "Error: " + msgstr "Erreur : " + +-#: plugins/copr.py:155 ++#: plugins/copr.py:165 + msgid "" + "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" + "copr_projectname` format" +@@ -309,19 +317,19 @@ msgstr "" + "précisez un hub Copr soit via `--hub` ou en utilisant le format `hub_copr/" + "utilisateur_copr/projet_copr`" + +-#: plugins/copr.py:158 ++#: plugins/copr.py:168 + msgid "multiple hubs specified" + msgstr "de multiples hubs ont été renseignés" + +-#: plugins/copr.py:223 plugins/copr.py:227 ++#: plugins/copr.py:237 plugins/copr.py:241 + msgid "exactly two additional parameters to copr command are required" + msgstr "la commande copr requiert exactement deux paramètres additionnels" + +-#: plugins/copr.py:232 ++#: plugins/copr.py:246 + msgid "Too many arguments." + msgstr "Trop d'arguments." + +-#: plugins/copr.py:235 ++#: plugins/copr.py:249 + msgid "" + "Bad format of optional chroot. The format is distribution-version-" + "architecture." +@@ -329,17 +337,17 @@ msgstr "" + "Mauvais format du chroot optionnel. Le format est distribution-version-" + "architecture." + +-#: plugins/copr.py:250 ++#: plugins/copr.py:264 + msgid "use format `copr_username/copr_projectname` to reference copr project" + msgstr "" + "utilisez le format `copr_username/copr_projectname` pour faire référence au " + "projet copr" + +-#: plugins/copr.py:252 ++#: plugins/copr.py:266 + msgid "bad copr project format" + msgstr "mauvais format de projet copr" + +-#: plugins/copr.py:266 ++#: plugins/copr.py:280 + msgid "" + "\n" + "Enabling a Copr repository. Please note that this repository is not part\n" +@@ -368,23 +376,23 @@ msgstr "" + "de Fedora.\n" + "En cas de problèmes, contactez le propriétaire de ce dépôt.\n" + +-#: plugins/copr.py:283 ++#: plugins/copr.py:297 + msgid "Repository successfully enabled." + msgstr "Activation du dépôt réussie." + +-#: plugins/copr.py:288 ++#: plugins/copr.py:302 + msgid "Repository successfully disabled." + msgstr "Désactivation du dépôt réussie." + +-#: plugins/copr.py:292 ++#: plugins/copr.py:306 + msgid "Repository successfully removed." + msgstr "Suppression du dépôt réussie." + +-#: plugins/copr.py:296 plugins/copr.py:697 ++#: plugins/copr.py:310 plugins/copr.py:721 + msgid "Unknown subcommand {}." + msgstr "Sous-commande inconnue {}." + +-#: plugins/copr.py:353 ++#: plugins/copr.py:367 + msgid "" + "* These coprs have repo file with an old format that contains no information " + "about Copr hub - the default one was assumed. Re-enable the project to fix " +@@ -394,51 +402,89 @@ msgstr "" + "aucune information à propos de Copr hub - celui par défaut a été utilisé. " + "Réactivez le projet pour résoudre le problème." + +-#: plugins/copr.py:366 ++#: plugins/copr.py:380 + msgid "Can't parse repositories for username '{}'." + msgstr "" + "Ne peut analyser les dépôts pour y chercher le nom d’utilisateur « {} »." + +-#: plugins/copr.py:369 ++#: plugins/copr.py:383 + msgid "List of {} coprs" + msgstr "Liste de {} coprs" + +-#: plugins/copr.py:374 ++#: plugins/copr.py:388 + msgid "No description given" + msgstr "Aucune description fournie" + +-#: plugins/copr.py:386 ++#: plugins/copr.py:400 + msgid "Can't parse search for '{}'." + msgstr "Impossible d’analyser la recherche pour « {} »." + +-#: plugins/copr.py:389 ++#: plugins/copr.py:403 + msgid "Matched: {}" + msgstr "Correspondance : {}" + +-#: plugins/copr.py:394 ++#: plugins/copr.py:408 + msgid "No description given." + msgstr "Pas de description fournie." + +-#: plugins/copr.py:416 ++#: plugins/copr.py:430 + msgid "Safe and good answer. Exiting." + msgstr "Réponse sûre et exacte. Fin." + +-#: plugins/copr.py:423 ++#: plugins/copr.py:437 + msgid "This command has to be run under the root user." + msgstr "Cette commande requiert les privilèges du super utilisateur." + +-#: plugins/copr.py:485 ++#: plugins/copr.py:487 ++#, python-brace-format ++msgid "Request to {0} failed: {1} - {2}" ++msgstr "La demande à {0} a échoué : {1} - {2}" ++ ++#: plugins/copr.py:489 ++msgid "It wasn't possible to enable this project.\n" ++msgstr "Il n'a pas été possible d'activer ce projet.\n" ++ ++#: plugins/copr.py:494 ++#, python-brace-format ++msgid "Repository '{0}' does not exist in project '{1}'." ++msgstr "Le référentiel '{0}' n'existe pas dans le projet '{1}'." ++ ++#: plugins/copr.py:497 + msgid "" +-"This repository does not have any builds yet so you cannot enable it now." ++"\n" ++"Available repositories: " ++msgstr "" ++"\n" ++"Dépôts disponibles : " ++ ++#: plugins/copr.py:499 ++#, python-brace-format ++msgid "" ++"\n" ++"\n" ++"If you want to enable a non-default repository, use the following command:\n" ++" 'dnf copr enable {0} '\n" ++"But note that the installed repo file will likely need a manual modification." + msgstr "" +-"Ce dépôt ne contient pas encore d’exécutables vous ne pouvez donc pas " +-"l’activer." ++"\n" ++"\n" ++"Si vous voulez activer un référentiel autre que celui par défaut, utilisez " ++"la commande suivante :\n" ++" 'dnf copr enable {0} '\n" ++"Mais notez que le fichier repo installé devra probablement être modifié " ++"manuellement." + +-#: plugins/copr.py:488 +-msgid "Such repository does not exist." +-msgstr "Ce dépôt n’existe pas." ++#: plugins/copr.py:505 ++#, python-brace-format ++msgid "Project {0} does not exist." ++msgstr "Le projet {0} n'existe pas." + +-#: plugins/copr.py:532 ++#: plugins/copr.py:508 ++#, python-brace-format ++msgid "Failed to connect to {0}: {1}" ++msgstr "Échec de la connexion à {0} : {1}" ++ ++#: plugins/copr.py:555 + #, python-brace-format + msgid "" + "Maintainer of the enabled Copr repository decided to make\n" +@@ -467,44 +513,44 @@ msgstr "" + "\n" + "Ces dépôts ont été activés automatiquement." + +-#: plugins/copr.py:553 ++#: plugins/copr.py:576 + msgid "Do you want to keep them enabled?" + msgstr "Souhaitez-vous les maintenir activés ?" + +-#: plugins/copr.py:586 ++#: plugins/copr.py:609 + #, python-brace-format + msgid "Failed to remove copr repo {0}/{1}/{2}" + msgstr "Échec de la suppression du dépôt Copr {0}/{1}/{2}" + +-#: plugins/copr.py:597 ++#: plugins/copr.py:620 + msgid "Failed to disable copr repo {}/{}" + msgstr "Échec de la désactivation du dépôt copr {}/{}" + +-#: plugins/copr.py:615 plugins/copr.py:652 ++#: plugins/copr.py:638 plugins/copr.py:675 + msgid "Unknown response from server." + msgstr "Réponse inconnue du serveur." + +-#: plugins/copr.py:637 ++#: plugins/copr.py:660 + msgid "Interact with Playground repository." + msgstr "Interagit avec le dépôt Playground." + +-#: plugins/copr.py:643 ++#: plugins/copr.py:666 + msgid "Enabling a Playground repository." + msgstr "Activation d’un dépôt Playground." + +-#: plugins/copr.py:644 ++#: plugins/copr.py:667 + msgid "Do you want to continue?" + msgstr "Souhaitez-vous continuer ?" + +-#: plugins/copr.py:687 ++#: plugins/copr.py:711 + msgid "Playground repositories successfully enabled." + msgstr "Activation des dépôts Playground réussie." + +-#: plugins/copr.py:690 ++#: plugins/copr.py:714 + msgid "Playground repositories successfully disabled." + msgstr "Désactivation des dépôts Playground réussie." + +-#: plugins/copr.py:694 ++#: plugins/copr.py:718 + msgid "Playground repositories successfully updated." + msgstr "Mise à jour des dépôts Playground réussie." + +@@ -887,7 +933,7 @@ msgstr "" + + #: plugins/modulesync.py:166 + msgid "No mach for argument '{}'" +-msgstr "Pas de correspondance pour l'argument '{}'" ++msgstr "Aucune correspondance pour l'argument '{}'" + + #. TODO(jmracek) Shell we end with an error or with RC 1? + #: plugins/modulesync.py:198 +@@ -954,18 +1000,18 @@ msgid "Bad Action Line \"%s\": %s" + msgstr "Mauvaise ligne d’action « %s » : %s" + + #. unsupported state, skip it +-#: plugins/post-transaction-actions.py:130 ++#: plugins/post-transaction-actions.py:133 + #, python-format + msgid "Bad Transaction State: %s" + msgstr "Mauvais état de transaction : %s" + +-#: plugins/post-transaction-actions.py:157 +-#: plugins/post-transaction-actions.py:159 ++#: plugins/post-transaction-actions.py:160 ++#: plugins/post-transaction-actions.py:162 + #, python-format + msgid "post-transaction-actions: %s" + msgstr "post-transaction-actions : %s" + +-#: plugins/post-transaction-actions.py:161 ++#: plugins/post-transaction-actions.py:164 + #, python-format + msgid "post-transaction-actions: Bad Command \"%s\": %s" + msgstr "post-transaction-actions : mauvaise commande « %s » : %s" +@@ -1152,31 +1198,43 @@ msgstr "Gère un dossier de paquets rpm" + msgid "Pass either --old or --new, not both!" + msgstr "Passez soit --old, soit --new, mais pas les deux !" + +-#: plugins/repomanage.py:89 ++#: plugins/repomanage.py:61 ++msgid "Pass either --oldonly or --new, not both!" ++msgstr "Passez soit --oldonly, soit --new, mais pas les deux !" ++ ++#: plugins/repomanage.py:63 ++msgid "Pass either --old or --oldonly, not both!" ++msgstr "Passez --old ou --oldonly, mais pas les deux !" ++ ++#: plugins/repomanage.py:100 + msgid "No files to process" + msgstr "Aucun fichier à traiter" + +-#: plugins/repomanage.py:96 ++#: plugins/repomanage.py:107 + msgid "Could not open {}" + msgstr "Ouverture de {} impossible" + +-#: plugins/repomanage.py:180 ++#: plugins/repomanage.py:223 + msgid "Print the older packages" + msgstr "Afficher les paquets plus anciens" + +-#: plugins/repomanage.py:182 ++#: plugins/repomanage.py:225 ++msgid "Print the older packages. Exclude the newest packages." ++msgstr "Afficher les anciens paquets. Exclure les paquets les plus récents." ++ ++#: plugins/repomanage.py:227 + msgid "Print the newest packages" + msgstr "Afficher les paquets les plus récents" + +-#: plugins/repomanage.py:184 ++#: plugins/repomanage.py:229 + msgid "Space separated output, not newline" + msgstr "Sorties séparées par des espaces plutôt que des retours à la ligne" + +-#: plugins/repomanage.py:186 ++#: plugins/repomanage.py:231 + msgid "Newest N packages to keep - defaults to 1" + msgstr "N paquets les plus récents à conserver — par défaut 1" + +-#: plugins/repomanage.py:189 ++#: plugins/repomanage.py:234 + msgid "Path to directory" + msgstr "Chemin vers le répertoire" + +@@ -1287,6 +1345,199 @@ msgstr "comps.xml pour le dépôt %s sauvegardé" + msgid "New leaves:" + msgstr "Nouvelles feuilles :" + ++#. Translators: This string is only used in unit tests. ++#: plugins/system_upgrade.py:45 ++msgid "the color of the sky" ++msgstr "la couleur du ciel" ++ ++#: plugins/system_upgrade.py:57 ++msgid "Need a --releasever greater than the current system version." ++msgstr "Besoin d'un --releasever supérieur à la version actuelle du système." ++ ++#. Translators: do not change "reboot" here ++#: plugins/system_upgrade.py:59 ++#, python-brace-format ++msgid "" ++"Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++"To remove cached metadata and transaction use 'dnf {command} clean'" ++msgstr "" ++"Téléchargement terminé ! Utilisez 'dnf {command} reboot' pour démarrer la " ++"mise à jour.\n" ++"Pour supprimer les métadonnées mises en cache et les transactions, utilisez " ++"'dnf {command} clean'’" ++ ++#: plugins/system_upgrade.py:62 ++msgid "Sorry, you need to use 'download --releasever' instead of '--network'" ++msgstr "" ++"Désolé, vous devez utiliser 'download --releasever' au lieu de '--network'’" ++ ++#: plugins/system_upgrade.py:71 ++msgid "Reboot turned off, not rebooting." ++msgstr "Redémarrage désactivé, pas de redémarrage." ++ ++#: plugins/system_upgrade.py:122 ++#, python-format ++msgid "Screen blanking can't be disabled: %s" ++msgstr "L'effacement d'écran ne peut pas être désactivé : %s" ++ ++#: plugins/system_upgrade.py:142 ++#, python-format ++msgid "Failed loading state file: %s, continuing with empty state." ++msgstr "" ++"Échec du chargement du fichier d'état : %s, continuer avec un état vide." ++ ++#: plugins/system_upgrade.py:289 ++msgid "The following boots appear to contain upgrade logs:" ++msgstr "" ++"Les démarrages suivants semblent contenir des journaux de mise à niveau :" ++ ++#: plugins/system_upgrade.py:299 ++msgid "-- no logs were found --" ++msgstr "-- aucun journal n'a été trouvé --" ++ ++#: plugins/system_upgrade.py:314 ++msgid "Cannot find logs with this index." ++msgstr "Impossible de trouver des journaux avec cet index." ++ ++#: plugins/system_upgrade.py:323 ++msgid "Unable to match systemd journal entry" ++msgstr "Impossible de faire correspondre l'entrée du journal de systemd" ++ ++#: plugins/system_upgrade.py:344 ++msgid "Prepare system for upgrade to a new release" ++msgstr "Préparer le système pour la mise à niveau vers une nouvelle version" ++ ++#: plugins/system_upgrade.py:360 ++msgid "keep installed packages if the new release's version is older" ++msgstr "" ++"Conserver les paquets installés si la version de la nouvelle version est " ++"plus ancienne" ++ ++#: plugins/system_upgrade.py:364 ++msgid "which logs to show" ++msgstr "Quels journaux afficher" ++ ++#: plugins/system_upgrade.py:398 ++#, python-brace-format ++msgid "Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++msgstr "" ++"Version incompatible des données. Relancez 'dnf {command} download " ++"[OPTIONS]'’" ++ ++#: plugins/system_upgrade.py:434 ++msgid "Command 'offline-distrosync' cannot be used with --no-downgrade option" ++msgstr "" ++"La commande 'offline-distrosync' ne peut pas être utilisée avec l'option " ++"--no-downgrade" ++ ++#: plugins/system_upgrade.py:454 ++msgid "" ++"WARNING: this operation is not supported on the RHEL distribution. Proceed " ++"at your own risk." ++msgstr "" ++"AVERTISSEMENT : cette opération n'est pas prise en charge sur la " ++"distribution RHEL. Procédez à vos propres risques." ++ ++#: plugins/system_upgrade.py:458 ++msgid "Additional information for System Upgrade: {}" ++msgstr "Informations supplémentaires pour la mise à niveau du système : {}" ++ ++#: plugins/system_upgrade.py:461 ++msgid "" ++"Before you continue ensure that your system is fully upgraded by running " ++"\"dnf --refresh upgrade\". Do you want to continue" ++msgstr "" ++"Avant de continuer, assurez-vous que votre système est entièrement mis à " ++"jour en exécutant \"dnf --refresh upgrade\". Voulez-vous continuer" ++ ++#: plugins/system_upgrade.py:465 ++msgid "Operation aborted." ++msgstr "Opération avortée." ++ ++#: plugins/system_upgrade.py:526 ++msgid "system is not ready for upgrade" ++msgstr "Le système n'est pas prêt pour la mise à niveau" ++ ++#: plugins/system_upgrade.py:529 ++#, python-brace-format ++msgid "" ++"the transaction was not prepared for '{command}'. Rerun 'dnf {command} " ++"download [OPTIONS]'" ++msgstr "" ++"La transaction n'a pas été préparée pour '{command}'. Relancez 'dnf {command}" ++" download [OPTIONS]'" ++ ++#: plugins/system_upgrade.py:533 ++msgid "upgrade is already scheduled" ++msgstr "la mise à niveau est déjà prévue" ++ ++#: plugins/system_upgrade.py:539 ++msgid "trigger file does not exist. exiting quietly." ++msgstr "Le fichier de déclenchement n'existe pas. Il se termine tranquillement." ++ ++#: plugins/system_upgrade.py:542 ++msgid "another upgrade tool is running. exiting quietly." ++msgstr "" ++"Un autre outil de mise à niveau est en cours d'exécution. il se termine " ++"tranquillement." ++ ++#: plugins/system_upgrade.py:551 ++#, python-brace-format ++msgid "use 'dnf {command} reboot' to begin the upgrade" ++msgstr "Utilisez 'dnf {command} reboot' pour commencer la mise à jour" ++ ++#: plugins/system_upgrade.py:569 ++msgid "Rebooting to perform upgrade." ++msgstr "Redémarrage pour effectuer la mise à niveau." ++ ++#: plugins/system_upgrade.py:602 ++msgid "Starting offline upgrade. This will take a while." ++msgstr "" ++"Je commence la mise à jour hors ligne. Cela va prendre un certain temps." ++ ++#: plugins/system_upgrade.py:604 ++msgid "Starting offline distrosync. This will take a while." ++msgstr "" ++"Démarrage de la distrosync hors ligne. Cela va prendre un certain temps." ++ ++#: plugins/system_upgrade.py:606 ++msgid "Starting system upgrade. This will take a while." ++msgstr "" ++"Je commence la mise à jour du système. Cela va prendre un certain temps." ++ ++#: plugins/system_upgrade.py:622 ++msgid "Cleaning up downloaded data..." ++msgstr "Nettoyage des données téléchargées..." ++ ++#: plugins/system_upgrade.py:652 ++msgid "" ++"The system-upgrade transaction is empty, your system is already up-to-date." ++msgstr "La transaction system-upgrade est vide, votre système est déjà à jour." ++ ++#: plugins/system_upgrade.py:661 ++msgid "Transaction saved to {}." ++msgstr "Transaction enregistrée vers {}." ++ ++#: plugins/system_upgrade.py:664 ++msgid "Error storing transaction: {}" ++msgstr "Erreur lors du stockage de la transaction : {}" ++ ++#: plugins/system_upgrade.py:686 ++msgid "Download finished." ++msgstr "Téléchargement terminé." ++ ++#: plugins/system_upgrade.py:689 plugins/system_upgrade.py:690 ++msgid "Upgrade complete! Cleaning up and rebooting..." ++msgstr "Mise à jour terminée ! Nettoyage et redémarrage..." ++ ++#: plugins/system_upgrade.py:699 ++msgid "Prepare offline upgrade of the system" ++msgstr "Préparer la mise à niveau hors ligne du système" ++ ++#: plugins/system_upgrade.py:704 ++msgid "Prepare offline distrosync of the system" ++msgstr "Préparer la distrosynchronisation hors ligne du système" ++ + #: plugins/versionlock.py:33 + #, python-format + msgid "Unable to read version lock configuration: %s" +@@ -1361,6 +1612,12 @@ msgstr "" + "La sous-commande '{}' est obsolète. Utilisez plutôt la sous-commande " + "'exclude'." + ++#~ msgid "" ++#~ "This repository does not have any builds yet so you cannot enable it now." ++#~ msgstr "" ++#~ "Ce dépôt ne contient pas encore d’exécutables vous ne pouvez donc pas " ++#~ "l’activer." ++ + #~ msgid "" + #~ "\n" + #~ "These repositories have been enabled automatically.\n" +diff --git a/po/ja.po b/po/ja.po +index c5c4691..2119fbe 100644 +--- a/po/ja.po ++++ b/po/ja.po +@@ -1,15 +1,15 @@ + # Ooyama Yosiyuki , 2015. #zanata +-# Ludek Janda , 2018. #zanata, 2021. ++# Ludek Janda , 2018. #zanata, 2021, 2023. + # Casey Jones , 2020. + # Sundeep Anand , 2021. +-# Transtats , 2022. ++# Transtats , 2022, 2023. + msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2022-02-28 11:53+0100\n" +-"PO-Revision-Date: 2022-03-09 12:39+0000\n" +-"Last-Translator: Transtats \n" ++"POT-Creation-Date: 2023-02-28 12:21+0100\n" ++"PO-Revision-Date: 2023-03-06 13:48+0000\n" ++"Last-Translator: Ludek Janda \n" + "Language-Team: Japanese \n" + "Language: ja\n" +@@ -17,7 +17,7 @@ msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=1; plural=0;\n" +-"X-Generator: Weblate 4.11.2\n" ++"X-Generator: Weblate 4.15.2\n" + + #: plugins/builddep.py:45 + msgid "[PACKAGE|PACKAGE.spec]" +@@ -69,16 +69,22 @@ msgid "Failed to open: '%s', not a valid source rpm file." + msgstr "" + "開くことに失敗しました: '%s'、有効なソース rpm ファイルではありません。" + +-#: plugins/builddep.py:204 plugins/builddep.py:220 plugins/builddep.py:237 ++#: plugins/builddep.py:204 plugins/builddep.py:224 plugins/builddep.py:241 + msgid "Not all dependencies satisfied" + msgstr "すべての依存関係が満たされているわけではない" + +-#: plugins/builddep.py:211 ++#: plugins/builddep.py:208 ++msgid "" ++"Warning: -D or --define arguments have no meaning for source rpm packages." ++msgstr "警告: -D または --define 引数には、ソース rpm " ++"パッケージに対する意味はありません。" ++ ++#: plugins/builddep.py:215 + #, python-format + msgid "Failed to open: '%s', not a valid spec file: %s" + msgstr "開くことに失敗しました: '%s'、有効なスペックファイルではありません: %s" + +-#: plugins/builddep.py:230 plugins/repoclosure.py:118 ++#: plugins/builddep.py:234 plugins/repoclosure.py:118 + #, python-format + msgid "no package matched: %s" + msgstr "一致するパッケージはありません: %s" +@@ -209,27 +215,27 @@ msgstr[0] "repo の設定に失敗しました" + msgid "Could not save repo to repofile %s: %s" + msgstr "repofile %s に repo を保存できませんでした: %s" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "y" + msgstr "y" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "yes" + msgstr "はい" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "n" + msgstr "n" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "no" + msgstr "いいえ" + +-#: plugins/copr.py:84 ++#: plugins/copr.py:92 + msgid "Interact with Copr repositories." + msgstr "Copr リポジトリーとの対話。" + +-#: plugins/copr.py:86 ++#: plugins/copr.py:94 + msgid "" + "\n" + " enable name/project [chroot]\n" +@@ -267,32 +273,32 @@ msgstr "" + " copr search tests\n" + " " + +-#: plugins/copr.py:112 ++#: plugins/copr.py:120 + msgid "List all installed Copr repositories (default)" + msgstr "" + "インストール済みのすべての Copr リポジトリーを一覧表示します (デフォルト)" + +-#: plugins/copr.py:114 ++#: plugins/copr.py:122 + msgid "List enabled Copr repositories" + msgstr "有効化された Copr リポジトリーを一覧表示します" + +-#: plugins/copr.py:116 ++#: plugins/copr.py:124 + msgid "List disabled Copr repositories" + msgstr "無効化された Copr リポジトリーを一覧表示します" + +-#: plugins/copr.py:118 ++#: plugins/copr.py:126 + msgid "List available Copr repositories by user NAME" + msgstr "利用可能な Copr リポジトリーをユーザー NAME ごとに一覧表示します" + +-#: plugins/copr.py:120 ++#: plugins/copr.py:128 + msgid "Specify an instance of Copr to work with" + msgstr "作業する Copr のインスタンスを指定します" + +-#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 ++#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 + msgid "Error: " + msgstr "エラー: " + +-#: plugins/copr.py:155 ++#: plugins/copr.py:165 + msgid "" + "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" + "copr_projectname` format" +@@ -300,36 +306,37 @@ msgstr "" + "`--hub` または `copr_hub/copr_username/copr_projectname` フォーマットを使っ" + "て、Copr ハブを指定します" + +-#: plugins/copr.py:158 ++#: plugins/copr.py:168 + msgid "multiple hubs specified" + msgstr "複数のハブが指定されています" + +-#: plugins/copr.py:223 plugins/copr.py:227 ++#: plugins/copr.py:237 plugins/copr.py:241 + msgid "exactly two additional parameters to copr command are required" + msgstr "copr コマンドに厳密に 2 つの追加パラメーターが必要です" + +-#: plugins/copr.py:232 ++#: plugins/copr.py:246 + msgid "Too many arguments." + msgstr "引数が多すぎます。" + +-#: plugins/copr.py:235 ++#: plugins/copr.py:249 + msgid "" + "Bad format of optional chroot. The format is distribution-version-" + "architecture." +-msgstr "オプションの chroot の形式が無効です。正しい形式は distribution-version-" ++msgstr "" ++"オプションの chroot の形式が無効です。正しい形式は distribution-version-" + "architecture です。" + +-#: plugins/copr.py:250 ++#: plugins/copr.py:264 + msgid "use format `copr_username/copr_projectname` to reference copr project" + msgstr "" + "copr プロジェクトを参照するには `copr_username/copr_projectname` 形式を使用し" + "ます" + +-#: plugins/copr.py:252 ++#: plugins/copr.py:266 + msgid "bad copr project format" + msgstr "不正な copr プロジェクト形式" + +-#: plugins/copr.py:266 ++#: plugins/copr.py:280 + msgid "" + "\n" + "Enabling a Copr repository. Please note that this repository is not part\n" +@@ -358,23 +365,23 @@ msgstr "" + "Fedora Bugzilla でこれらのパッケージに関するバグ報告をしないでください。\n" + "問題が発生した場合は、このリポジトリーのオーナーに連絡してください。\n" + +-#: plugins/copr.py:283 ++#: plugins/copr.py:297 + msgid "Repository successfully enabled." + msgstr "リポジトリが正常に有効化されました。" + +-#: plugins/copr.py:288 ++#: plugins/copr.py:302 + msgid "Repository successfully disabled." + msgstr "リポジトリが正常に無効化されました。" + +-#: plugins/copr.py:292 ++#: plugins/copr.py:306 + msgid "Repository successfully removed." + msgstr "リポジトリーが正常に削除されました。" + +-#: plugins/copr.py:296 plugins/copr.py:697 ++#: plugins/copr.py:310 plugins/copr.py:721 + msgid "Unknown subcommand {}." + msgstr "不明なサブコマンド {}。" + +-#: plugins/copr.py:353 ++#: plugins/copr.py:367 + msgid "" + "* These coprs have repo file with an old format that contains no information " + "about Copr hub - the default one was assumed. Re-enable the project to fix " +@@ -384,49 +391,87 @@ msgstr "" + "ファイルがあります。デフォルトは仮定です。これを修正するには、プロジェクトを" + "再度有効化してください。" + +-#: plugins/copr.py:366 ++#: plugins/copr.py:380 + msgid "Can't parse repositories for username '{}'." + msgstr "ユーザー名 '{}' のリポジトリーを解析できません。" + +-#: plugins/copr.py:369 ++#: plugins/copr.py:383 + msgid "List of {} coprs" + msgstr "{} coprs の一覧" + +-#: plugins/copr.py:374 ++#: plugins/copr.py:388 + msgid "No description given" + msgstr "説明がありません" + +-#: plugins/copr.py:386 ++#: plugins/copr.py:400 + msgid "Can't parse search for '{}'." + msgstr "'{}' の検索を解析できません。" + +-#: plugins/copr.py:389 ++#: plugins/copr.py:403 + msgid "Matched: {}" + msgstr "一致: {}" + +-#: plugins/copr.py:394 ++#: plugins/copr.py:408 + msgid "No description given." + msgstr "説明が与えられていません。" + +-#: plugins/copr.py:416 ++#: plugins/copr.py:430 + msgid "Safe and good answer. Exiting." + msgstr "安全で優れた回答。終了中。" + +-#: plugins/copr.py:423 ++#: plugins/copr.py:437 + msgid "This command has to be run under the root user." + msgstr "このコマンドは root ユーザーの下で実行する必要があります。" + +-#: plugins/copr.py:485 ++#: plugins/copr.py:487 ++#, python-brace-format ++msgid "Request to {0} failed: {1} - {2}" ++msgstr "{0} へのリクエストに失敗しました: {1} - {2}" ++ ++#: plugins/copr.py:489 ++msgid "It wasn't possible to enable this project.\n" ++msgstr "このプロジェクトを有効にすることができませんでした。\n" ++ ++#: plugins/copr.py:494 ++#, python-brace-format ++msgid "Repository '{0}' does not exist in project '{1}'." ++msgstr "'{0}' リポジトリーはプロジェクト '{1}' に存在しません。" ++ ++#: plugins/copr.py:497 + msgid "" +-"This repository does not have any builds yet so you cannot enable it now." ++"\n" ++"Available repositories: " + msgstr "" +-"このリポジトリーにはまだビルドがありませんので、今すぐ有効化できません。" ++"\n" ++"利用可能なリポジトリー: " ++ ++#: plugins/copr.py:499 ++#, python-brace-format ++msgid "" ++"\n" ++"\n" ++"If you want to enable a non-default repository, use the following command:\n" ++" 'dnf copr enable {0} '\n" ++"But note that the installed repo file will likely need a manual modification." ++msgstr "" ++"\n" ++"\n" ++"デフォルト以外のリポジトリーを有効にする場合は、以下のコマンドを使用します:\n" ++" 'dnf copr enable {0} '\n" ++"ただし、インストールされているリポジトリーファイルを手動で変更する必要がある" ++"可能性があることに注意してください。" + +-#: plugins/copr.py:488 +-msgid "Such repository does not exist." +-msgstr "そのようなリポジトリーは存在しません。" ++#: plugins/copr.py:505 ++#, python-brace-format ++msgid "Project {0} does not exist." ++msgstr "プロジェクト {0} は存在しません。" ++ ++#: plugins/copr.py:508 ++#, python-brace-format ++msgid "Failed to connect to {0}: {1}" ++msgstr "{0} への接続に失敗しました: {1}" + +-#: plugins/copr.py:532 ++#: plugins/copr.py:555 + #, python-brace-format + msgid "" + "Maintainer of the enabled Copr repository decided to make\n" +@@ -444,8 +489,8 @@ msgid "" + msgstr "" + "有効化した Copr リポジトリーの管理者は\n" + "他のリポジトリーに依存するように決めました。\n" +-"そのようなリポジトリーは通常、主な Corp " +-"レジストリー(ランタイム依存関係を提供) から RPM を\n" ++"そのようなリポジトリーは通常、主な Corp レジストリー(ランタイム依存関係を提" ++"供) から RPM を\n" + "正常にインストールするために必要です。\n" + "\n" + "上記の品質とバグ報告についての注意点がここでも適用\n" +@@ -456,44 +501,44 @@ msgstr "" + "\n" + "これらのリポジトリーは自動的に有効になっています。" + +-#: plugins/copr.py:553 ++#: plugins/copr.py:576 + msgid "Do you want to keep them enabled?" + msgstr "有効にしておきますか?" + +-#: plugins/copr.py:586 ++#: plugins/copr.py:609 + #, python-brace-format + msgid "Failed to remove copr repo {0}/{1}/{2}" + msgstr "copr repo {0}/{1}/{2} の削除に失敗しました" + +-#: plugins/copr.py:597 ++#: plugins/copr.py:620 + msgid "Failed to disable copr repo {}/{}" + msgstr "copr repo {}/{} の無効化に失敗しました" + +-#: plugins/copr.py:615 plugins/copr.py:652 ++#: plugins/copr.py:638 plugins/copr.py:675 + msgid "Unknown response from server." + msgstr "サーバーからの不明な応答です。" + +-#: plugins/copr.py:637 ++#: plugins/copr.py:660 + msgid "Interact with Playground repository." + msgstr "Playground リポジトリーとの対話。" + +-#: plugins/copr.py:643 ++#: plugins/copr.py:666 + msgid "Enabling a Playground repository." + msgstr "Playgroundのリポジトリーの有効化。" + +-#: plugins/copr.py:644 ++#: plugins/copr.py:667 + msgid "Do you want to continue?" + msgstr "続行しますか?" + +-#: plugins/copr.py:687 ++#: plugins/copr.py:711 + msgid "Playground repositories successfully enabled." + msgstr "Playground リポジトリーが正常に有効化されました。" + +-#: plugins/copr.py:690 ++#: plugins/copr.py:714 + msgid "Playground repositories successfully disabled." + msgstr "Playground リポジトリーが正常に無効化されました。" + +-#: plugins/copr.py:694 ++#: plugins/copr.py:718 + msgid "Playground repositories successfully updated." + msgstr "Playground リポジトリーが正常に更新されました。" + +@@ -822,7 +867,8 @@ msgstr "履歴データを移行中..." + #: plugins/modulesync.py:37 + msgid "" + "Download packages from modules and/or create a repository with modular data" +-msgstr "モジュールからパッケージをダウンロードしたり、モジュラーデータでリポジトリー" ++msgstr "" ++"モジュールからパッケージをダウンロードしたり、モジュラーデータでリポジトリー" + "を作成したりします" + + #: plugins/modulesync.py:44 +@@ -839,8 +885,9 @@ msgstr "ソースパッケージを含むリポジトリーを有効にします + + #: plugins/modulesync.py:49 + msgid "enable repositories with debug-info and debug-source packages" +-msgstr "debug-info パッケージおよび debug-source " +-"パッケージでリポジトリーを有効にします" ++msgstr "" ++"debug-info パッケージおよび debug-source パッケージでリポジトリーを有効にしま" ++"す" + + #: plugins/modulesync.py:53 + msgid "download only packages from newest modules" +@@ -855,8 +902,9 @@ msgstr[0] "引数に一致するものが見つかりませんでした: '{}'" + msgid "" + "Creation of repository failed with return code {}. All downloaded content " + "was kept on the system" +-msgstr "リポジトリーの作成は戻りコード {} " +-"で失敗しました。ダウンロードされたコンテンツはすべてシステムに保持されました" ++msgstr "" ++"リポジトリーの作成は戻りコード {} で失敗しました。ダウンロードされたコンテン" ++"ツはすべてシステムに保持されました" + + #: plugins/modulesync.py:144 + #, python-brace-format +@@ -866,8 +914,9 @@ msgstr "モジュール '{1}' のアーティファクト '{0}' に一致する + #: plugins/modulesync.py:162 + #, python-brace-format + msgid "No match for package name '{0}' in profile {1} from module {2}" +-msgstr "モジュール {2} からのプロファイル {1} のパッケージ名 '{0}' " +-"に一致するものはありません" ++msgstr "" ++"モジュール {2} からのプロファイル {1} のパッケージ名 '{0}' に一致するものはあ" ++"りません" + + #: plugins/modulesync.py:166 + msgid "No mach for argument '{}'" +@@ -884,8 +933,8 @@ msgid "" + "No installed package found for package name \"{pkg}\" specified in needs-" + "restarting file \"{file}\"." + msgstr "" +-"needs-restarting ファイル \"{file}\" に指定されている \"{pkg}\" " +-"というパッケージのインストール済みパッケージが見つかりません。" ++"needs-restarting ファイル \"{file}\" に指定されている \"{pkg}\" というパッ" ++"ケージのインストール済みパッケージが見つかりません。" + + #: plugins/needs_restarting.py:220 + msgid "determine updated binaries that need restarting" +@@ -932,18 +981,18 @@ msgid "Bad Action Line \"%s\": %s" + msgstr "不正なアクション行 \"%s\": %s" + + #. unsupported state, skip it +-#: plugins/post-transaction-actions.py:130 ++#: plugins/post-transaction-actions.py:133 + #, python-format + msgid "Bad Transaction State: %s" + msgstr "不正なトランザクション状態: %s" + +-#: plugins/post-transaction-actions.py:157 +-#: plugins/post-transaction-actions.py:159 ++#: plugins/post-transaction-actions.py:160 ++#: plugins/post-transaction-actions.py:162 + #, python-format + msgid "post-transaction-actions: %s" + msgstr "post-transaction-actions: %s" + +-#: plugins/post-transaction-actions.py:161 ++#: plugins/post-transaction-actions.py:164 + #, python-format + msgid "post-transaction-actions: Bad Command \"%s\": %s" + msgstr "post-transaction-actions: 不正なコマンド \"%s\": %s" +@@ -1126,33 +1175,45 @@ msgstr "rpm パッケージのディレクトリーを管理します" + + #: plugins/repomanage.py:59 + msgid "Pass either --old or --new, not both!" +-msgstr "--old または --new のいずれかを渡します。両方ではありません。" ++msgstr "--old または --new のいずれかを渡します、両方ではありません!" ++ ++#: plugins/repomanage.py:61 ++msgid "Pass either --oldonly or --new, not both!" ++msgstr "--oldonly または --new のいずれかを渡します、両方ではありません!" ++ ++#: plugins/repomanage.py:63 ++msgid "Pass either --old or --oldonly, not both!" ++msgstr "--old または --oldonly のいずれかを渡します、両方ではありません!" + +-#: plugins/repomanage.py:89 ++#: plugins/repomanage.py:100 + msgid "No files to process" + msgstr "処理するファイルはありません" + +-#: plugins/repomanage.py:96 ++#: plugins/repomanage.py:107 + msgid "Could not open {}" + msgstr "{} を開くことができません" + +-#: plugins/repomanage.py:180 ++#: plugins/repomanage.py:223 + msgid "Print the older packages" + msgstr "古いパッケージを印刷します" + +-#: plugins/repomanage.py:182 ++#: plugins/repomanage.py:225 ++msgid "Print the older packages. Exclude the newest packages." ++msgstr "古いパッケージを出力します。最新のパッケージを除外します。" ++ ++#: plugins/repomanage.py:227 + msgid "Print the newest packages" + msgstr "最新のパッケージを印刷します" + +-#: plugins/repomanage.py:184 ++#: plugins/repomanage.py:229 + msgid "Space separated output, not newline" + msgstr "スペースで区切られた出力で、改行ではありません" + +-#: plugins/repomanage.py:186 ++#: plugins/repomanage.py:231 + msgid "Newest N packages to keep - defaults to 1" + msgstr "維持する最新の N パッケージ - デフォルトは 1 に設定されます" + +-#: plugins/repomanage.py:189 ++#: plugins/repomanage.py:234 + msgid "Path to directory" + msgstr "ディレクトリーへのパス" + +@@ -1259,6 +1320,186 @@ msgid "New leaves:" + msgstr "" + "新規のリーフパッケージ (他のパッケージから依存されていないパッケージ) :" + ++#. Translators: This string is only used in unit tests. ++#: plugins/system_upgrade.py:45 ++msgid "the color of the sky" ++msgstr "Sky の色" ++ ++#: plugins/system_upgrade.py:57 ++msgid "Need a --releasever greater than the current system version." ++msgstr "現在のシステムバージョンよりも大きい --releasever が必要です。" ++ ++#. Translators: do not change "reboot" here ++#: plugins/system_upgrade.py:59 ++#, python-brace-format ++msgid "" ++"Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++"To remove cached metadata and transaction use 'dnf {command} clean'" ++msgstr "" ++"ダウンロードが完了しました! 'dnf {command} reboot' " ++"を使用して、アップグレードを開始します。\n" ++"キャッシュしたメタデータやトランザクションを削除するには、'dnf {command} " ++"clean' を使用します』" ++ ++#: plugins/system_upgrade.py:62 ++msgid "Sorry, you need to use 'download --releasever' instead of '--network'" ++msgstr "申し訳ございません。'--network' の代わりに 'download --releasever' " ++"を使用する必要があります』" ++ ++#: plugins/system_upgrade.py:71 ++msgid "Reboot turned off, not rebooting." ++msgstr "再起動ではなく、再起動をオフにしました。" ++ ++#: plugins/system_upgrade.py:122 ++#, python-format ++msgid "Screen blanking can't be disabled: %s" ++msgstr "空白の画面は無効にできません: %s" ++ ++#: plugins/system_upgrade.py:142 ++#, python-format ++msgid "Failed loading state file: %s, continuing with empty state." ++msgstr "状態ファイルの読み込みに失敗: %s、空の状態で続行。" ++ ++#: plugins/system_upgrade.py:289 ++msgid "The following boots appear to contain upgrade logs:" ++msgstr "以下のブートには、アップグレードログが含まれているように見えます:" ++ ++#: plugins/system_upgrade.py:299 ++msgid "-- no logs were found --" ++msgstr "-- ログが見つかりませんでした --" ++ ++#: plugins/system_upgrade.py:314 ++msgid "Cannot find logs with this index." ++msgstr "このインデックスのログが見つかりません。" ++ ++#: plugins/system_upgrade.py:323 ++msgid "Unable to match systemd journal entry" ++msgstr "systemd ジャーナルエントリーにマッチできない" ++ ++#: plugins/system_upgrade.py:344 ++msgid "Prepare system for upgrade to a new release" ++msgstr "新しいリリースへのアップグレードに向けたシステムの準備" ++ ++#: plugins/system_upgrade.py:360 ++msgid "keep installed packages if the new release's version is older" ++msgstr "新しいリリースのバージョンが古い場合は、インストール済みパッケージを維持しま" ++"す" ++ ++#: plugins/system_upgrade.py:364 ++msgid "which logs to show" ++msgstr "表示するログ" ++ ++#: plugins/system_upgrade.py:398 ++#, python-brace-format ++msgid "Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++msgstr "互換性のないバージョンのデータ。'dnf {command} download [OPTIONS]' " ++"を再実行します』" ++ ++#: plugins/system_upgrade.py:434 ++msgid "Command 'offline-distrosync' cannot be used with --no-downgrade option" ++msgstr "コマンド 'offline-distrosync' は --no-downgrade オプションと併用できません" ++ ++#: plugins/system_upgrade.py:454 ++msgid "" ++"WARNING: this operation is not supported on the RHEL distribution. Proceed " ++"at your own risk." ++msgstr "警告: この操作は RHEL ディストリビューションではサポートされていません。自己" ++"責任で続行してください。" ++ ++#: plugins/system_upgrade.py:458 ++msgid "Additional information for System Upgrade: {}" ++msgstr "システムアップグレードの追加情報: {}" ++ ++#: plugins/system_upgrade.py:461 ++msgid "" ++"Before you continue ensure that your system is fully upgraded by running " ++"\"dnf --refresh upgrade\". Do you want to continue" ++msgstr "続行する前に、dnf --refresh upgrade を実行して、システムが完全にアップグレー" ++"ドされていることを確認します。続行しますか" ++ ++#: plugins/system_upgrade.py:465 ++msgid "Operation aborted." ++msgstr "操作が中断されました。" ++ ++#: plugins/system_upgrade.py:526 ++msgid "system is not ready for upgrade" ++msgstr "システムがアップグレードの準備ができていません" ++ ++#: plugins/system_upgrade.py:529 ++#, python-brace-format ++msgid "" ++"the transaction was not prepared for '{command}'. Rerun 'dnf {command} " ++"download [OPTIONS]'" ++msgstr "" ++"トランザクションは '{command}' に対して準備されていません。'dnf {command} " ++"download [OPTIONS]' を再実行します』" ++ ++#: plugins/system_upgrade.py:533 ++msgid "upgrade is already scheduled" ++msgstr "アップグレードはすでにスケジュールされています" ++ ++#: plugins/system_upgrade.py:539 ++msgid "trigger file does not exist. exiting quietly." ++msgstr "トリガーファイルは存在しません。間もなく終了します。" ++ ++#: plugins/system_upgrade.py:542 ++msgid "another upgrade tool is running. exiting quietly." ++msgstr "別のアップグレードツールが実行中で、警告なしで終了します。" ++ ++#: plugins/system_upgrade.py:551 ++#, python-brace-format ++msgid "use 'dnf {command} reboot' to begin the upgrade" ++msgstr "'dnf {command} reboot' を使用してアップグレードを開始します" ++ ++#: plugins/system_upgrade.py:569 ++msgid "Rebooting to perform upgrade." ++msgstr "再起動してアップグレードを実行します。" ++ ++#: plugins/system_upgrade.py:602 ++msgid "Starting offline upgrade. This will take a while." ++msgstr "オフラインアップグレードの開始。これには時間がかかります。" ++ ++#: plugins/system_upgrade.py:604 ++msgid "Starting offline distrosync. This will take a while." ++msgstr "オフラインの distrosync の開始。これには時間がかかります。" ++ ++#: plugins/system_upgrade.py:606 ++msgid "Starting system upgrade. This will take a while." ++msgstr "システムのアップグレードを開始します。これには時間がかかります。" ++ ++#: plugins/system_upgrade.py:622 ++msgid "Cleaning up downloaded data..." ++msgstr "ダウンロードしたデータのクリーンアップ中..." ++ ++#: plugins/system_upgrade.py:652 ++msgid "" ++"The system-upgrade transaction is empty, your system is already up-to-date." ++msgstr "システムアップグレードトランザクションは空で、システムはすでに最新です。" ++ ++#: plugins/system_upgrade.py:661 ++msgid "Transaction saved to {}." ++msgstr "{} に保存されているトランザクション。" ++ ++#: plugins/system_upgrade.py:664 ++msgid "Error storing transaction: {}" ++msgstr "トランザクションの保存エラー: {}" ++ ++#: plugins/system_upgrade.py:686 ++msgid "Download finished." ++msgstr "ダウンロードが完了しました。" ++ ++#: plugins/system_upgrade.py:689 plugins/system_upgrade.py:690 ++msgid "Upgrade complete! Cleaning up and rebooting..." ++msgstr "アップグレードの完了! クリーンアップおよび再起動を行っています..." ++ ++#: plugins/system_upgrade.py:699 ++msgid "Prepare offline upgrade of the system" ++msgstr "システムのオフラインアップグレードの準備" ++ ++#: plugins/system_upgrade.py:704 ++msgid "Prepare offline distrosync of the system" ++msgstr "システムのオフラインの distrosync を準備します" ++ + #: plugins/versionlock.py:33 + #, python-format + msgid "Unable to read version lock configuration: %s" +@@ -1323,8 +1564,14 @@ msgstr "パッケージ仕様をそのまま使用し、解析を試みないで + + #: plugins/versionlock.py:160 + msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." +-msgstr "サブコマンド '{}' は非推奨になりました。代わりに 'exclude' " +-"サブコマンドを使用してください。" ++msgstr "" ++"サブコマンド '{}' は非推奨になりました。代わりに 'exclude' サブコマンドを使用" ++"してください。" ++ ++#~ msgid "" ++#~ "This repository does not have any builds yet so you cannot enable it now." ++#~ msgstr "" ++#~ "このリポジトリーにはまだビルドがありませんので、今すぐ有効化できません。" + + #~ msgid "" + #~ "\n" +diff --git a/po/ko.po b/po/ko.po +index 307ccc7..1b615d4 100644 +--- a/po/ko.po ++++ b/po/ko.po +@@ -1,13 +1,14 @@ + # Ludek Janda , 2018. #zanata, 2020. + # simmon , 2021. + # Kim InSoo , 2022. ++# 김인수 , 2022, 2023. + msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2022-02-28 11:53+0100\n" +-"PO-Revision-Date: 2022-03-02 04:16+0000\n" +-"Last-Translator: Kim InSoo \n" ++"POT-Creation-Date: 2023-02-28 12:21+0100\n" ++"PO-Revision-Date: 2023-03-03 04:20+0000\n" ++"Last-Translator: 김인수 \n" + "Language-Team: Korean \n" + "Language: ko\n" +@@ -15,7 +16,7 @@ msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=1; plural=0;\n" +-"X-Generator: Weblate 4.11\n" ++"X-Generator: Weblate 4.15.2\n" + + #: plugins/builddep.py:45 + msgid "[PACKAGE|PACKAGE.spec]" +@@ -28,7 +29,7 @@ msgstr "'%s'는 'MACRO EXPR' 형식이 아닙니다" + + #: plugins/builddep.py:90 + msgid "packages with builddeps to install" +-msgstr "설치 할 builddeps가 있는 꾸러미(package)" ++msgstr "설치 할 builddeps가 있는 꾸러미" + + #: plugins/builddep.py:93 + msgid "define a macro for spec file parsing" +@@ -36,7 +37,7 @@ msgstr "특정한 파일 구문분석을 위해 매크로를 정의한다" + + #: plugins/builddep.py:95 + msgid "skip build dependencies not available in repositories" +-msgstr "저장소에서 사용 할 수 없는 구성 의존성을 건너띄기 한다" ++msgstr "저장소에서 사용 할 수 없는 구성 의존성을 건너 뛰기 한다" + + #: plugins/builddep.py:98 + msgid "treat commandline arguments as spec files" +@@ -44,7 +45,7 @@ msgstr "명령줄 인수를 지정한 파일로 다룬다" + + #: plugins/builddep.py:100 + msgid "treat commandline arguments as source rpm" +-msgstr "명령줄 인수를 rpm 소스로 다룬다" ++msgstr "원천 rpm으로 명령줄 인수를 다룬다" + + #: plugins/builddep.py:144 + msgid "RPM: {}" +@@ -52,42 +53,48 @@ msgstr "RPM: {}" + + #: plugins/builddep.py:153 + msgid "Some packages could not be found." +-msgstr "몇몇 꾸러미(packages)를 찾을 수 없습니다." ++msgstr "몇몇 꾸러미를 찾을 수 없습니다." + + #. No provides, no files + #. Richdeps can have no matches but it could be correct (solver must decide later) + #: plugins/builddep.py:173 + #, python-format + msgid "No matching package to install: '%s'" +-msgstr "설치: '%s' 꾸러미(package)가 일치하지 않습니다" ++msgstr "설치: '%s' 꾸러미가 일치하지 않습니다" + + #: plugins/builddep.py:191 + #, python-format + msgid "Failed to open: '%s', not a valid source rpm file." + msgstr "여는데 실패하였습니다: '%s', 유효한 rpm 파일 출처가 아닙니다." + +-#: plugins/builddep.py:204 plugins/builddep.py:220 plugins/builddep.py:237 ++#: plugins/builddep.py:204 plugins/builddep.py:224 plugins/builddep.py:241 + msgid "Not all dependencies satisfied" + msgstr "모든 의존성을 만족하지 않습니다" + +-#: plugins/builddep.py:211 ++#: plugins/builddep.py:208 ++msgid "" ++"Warning: -D or --define arguments have no meaning for source rpm packages." ++msgstr "경고: -D 또는 --define 인수는 원천 rpm 꾸러미를 위해 의미를 가지고 있지 " ++"않습니다." ++ ++#: plugins/builddep.py:215 + #, python-format + msgid "Failed to open: '%s', not a valid spec file: %s" + msgstr "여는데 실패하였습니다 '%s', 지정한 파일: %s가 유효하지 않습니다" + +-#: plugins/builddep.py:230 plugins/repoclosure.py:118 ++#: plugins/builddep.py:234 plugins/repoclosure.py:118 + #, python-format + msgid "no package matched: %s" +-msgstr "일치하는 꾸러미(package) 없음: %s" ++msgstr "일치하는 꾸러미 없음: %s" + + #: plugins/changelog.py:37 + #, python-brace-format + msgid "Not a valid date: \"{0}\"." +-msgstr "유효한 날자가 아닙니다: \"{0}\"." ++msgstr "유효한 날짜가 아닙니다: \"{0}\"." + + #: plugins/changelog.py:43 + msgid "Show changelog data of packages" +-msgstr "꾸러미(packages)의 변화 기록자료를 보여줍니다" ++msgstr "꾸러미의 변화 기록자료를 보여줍니다" + + #: plugins/changelog.py:51 + msgid "" +@@ -99,19 +106,19 @@ msgstr "" + + #: plugins/changelog.py:55 + msgid "show given number of changelog entries per package" +-msgstr "주어진 수의 꾸러미(package) 마다 변화기록 항목을 보여줍니다" ++msgstr "주어진 수의 꾸러미 마다 변화기록 항목을 보여줍니다" + + #: plugins/changelog.py:58 + msgid "" + "show only new changelog entries for packages, that provide an upgrade for " + "some of already installed packages." + msgstr "" +-"몇몇 이미 설치된 꾸러미(package)들의 최신화를 제공하는 꾸러미를 위하여 새로" +-"운 변화기록만을 보여줍니다." ++"몇몇 이미 설치된 꾸러미들의 최신화를 제공하는 꾸러미를 위하여 새로운 변화기록" ++"만을 보여줍니다." + + #: plugins/changelog.py:60 + msgid "PACKAGE" +-msgstr "꾸러미(package)" ++msgstr "꾸러미" + + #: plugins/changelog.py:81 plugins/debuginfo-install.py:90 + #, python-format +@@ -146,7 +153,7 @@ msgstr "{prog} 환경 선택과 저장소 관리" + + #: plugins/config_manager.py:45 + msgid "repo to modify" +-msgstr "수정할 repo" ++msgstr "수정하려는 저장소" + + #: plugins/config_manager.py:48 + msgid "save the current options (useful with --setopt)" +@@ -202,29 +209,29 @@ msgstr[0] "저장소 구성에 실패했습니다" + #: plugins/config_manager.py:217 + #, python-format + msgid "Could not save repo to repofile %s: %s" +-msgstr "repofile에 repo를 저장할 수 없습니다. %s: %s" ++msgstr "repofile에 repo를 저장 할 수 없습니다. %s: %s" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "y" + msgstr "y" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "yes" + msgstr "예" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "n" + msgstr "n" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "no" + msgstr "아니" + +-#: plugins/copr.py:84 ++#: plugins/copr.py:92 + msgid "Interact with Copr repositories." + msgstr "Copr 저장소와 상호 작용하십시오." + +-#: plugins/copr.py:86 ++#: plugins/copr.py:94 + msgid "" + "\n" + " enable name/project [chroot]\n" +@@ -262,31 +269,31 @@ msgstr "" + " copr search tests\n" + " " + +-#: plugins/copr.py:112 ++#: plugins/copr.py:120 + msgid "List all installed Copr repositories (default)" + msgstr "설치된 모든 Copr 저장소 나열 (기본값)" + +-#: plugins/copr.py:114 ++#: plugins/copr.py:122 + msgid "List enabled Copr repositories" + msgstr "사용 가능한 Copr 저장소 목록" + +-#: plugins/copr.py:116 ++#: plugins/copr.py:124 + msgid "List disabled Copr repositories" + msgstr "비활성화 된 Copr 저장소 목록" + +-#: plugins/copr.py:118 ++#: plugins/copr.py:126 + msgid "List available Copr repositories by user NAME" + msgstr "사용자가 사용할 수있는 Copr 저장소를 나열합니다. NAME" + +-#: plugins/copr.py:120 ++#: plugins/copr.py:128 + msgid "Specify an instance of Copr to work with" + msgstr "일하는 Copr의 예를 지정합니다" + +-#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 ++#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 + msgid "Error: " + msgstr "오류: " + +-#: plugins/copr.py:155 ++#: plugins/copr.py:165 + msgid "" + "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" + "copr_projectname` format" +@@ -294,35 +301,35 @@ msgstr "" + "Corp hub를 `--hub` 또는 사용하기 `copr_hub/copr_username/copr_projectname`형" + "식으로 지정합니다" + +-#: plugins/copr.py:158 ++#: plugins/copr.py:168 + msgid "multiple hubs specified" + msgstr "지정된 여러 허브" + +-#: plugins/copr.py:223 plugins/copr.py:227 ++#: plugins/copr.py:237 plugins/copr.py:241 + msgid "exactly two additional parameters to copr command are required" + msgstr "copr 명령에 정확히 두 개의 추가 매개 변수가 필요합니다" + +-#: plugins/copr.py:232 ++#: plugins/copr.py:246 + msgid "Too many arguments." + msgstr "너무 많은 인수." + +-#: plugins/copr.py:235 ++#: plugins/copr.py:249 + msgid "" + "Bad format of optional chroot. The format is distribution-version-" + "architecture." + msgstr "선택적인 chroot의 나쁜 형식. 형식은 배포-버전-구조입니다." + +-#: plugins/copr.py:250 ++#: plugins/copr.py:264 + msgid "use format `copr_username/copr_projectname` to reference copr project" + msgstr "" + "copr 프로젝트를 참조하기 위해`copr_username / copr_projectname` 형식을 사용하" + "십시오" + +-#: plugins/copr.py:252 ++#: plugins/copr.py:266 + msgid "bad copr project format" + msgstr "나쁜 copr 프로젝트 형식" + +-#: plugins/copr.py:266 ++#: plugins/copr.py:280 + msgid "" + "\n" + "Enabling a Copr repository. Please note that this repository is not part\n" +@@ -352,23 +359,23 @@ msgstr "" + "페도라 버그질라에 이들 꾸러미에 대한 파일 결점 보고를 제출하지 마세요.\n" + "이들 문제는, 이들 저장소 소유자와 접촉하세요.\n" + +-#: plugins/copr.py:283 ++#: plugins/copr.py:297 + msgid "Repository successfully enabled." + msgstr "저장소가 사용 설정되었습니다." + +-#: plugins/copr.py:288 ++#: plugins/copr.py:302 + msgid "Repository successfully disabled." + msgstr "저장소가 사용 중지되었습니다." + +-#: plugins/copr.py:292 ++#: plugins/copr.py:306 + msgid "Repository successfully removed." + msgstr "저장소가 제거되었습니다." + +-#: plugins/copr.py:296 plugins/copr.py:697 ++#: plugins/copr.py:310 plugins/copr.py:721 + msgid "Unknown subcommand {}." + msgstr "알 수없는 부속 명령 {}." + +-#: plugins/copr.py:353 ++#: plugins/copr.py:367 + msgid "" + "* These coprs have repo file with an old format that contains no information " + "about Copr hub - the default one was assumed. Re-enable the project to fix " +@@ -377,48 +384,88 @@ msgstr "" + "* 이들 coprs은 Copr hub에 대하여 어떤 정보도 포함하지 않는 오래된 형태의 저장" + "소 파일을 갖고 있습니다. 이 문제를 수정하기 위하여 프로젝트를 재활성화하세요." + +-#: plugins/copr.py:366 ++#: plugins/copr.py:380 + msgid "Can't parse repositories for username '{}'." + msgstr "사용자 이름 '{}'에 대한 리포지토리를 구문 분석 할 수 없습니다." + +-#: plugins/copr.py:369 ++#: plugins/copr.py:383 + msgid "List of {} coprs" + msgstr "{} 명의 경찰 목록" + +-#: plugins/copr.py:374 ++#: plugins/copr.py:388 + msgid "No description given" + msgstr "설명이 없습니다" + +-#: plugins/copr.py:386 ++#: plugins/copr.py:400 + msgid "Can't parse search for '{}'." + msgstr "'{}'에 대한 검색을 구문 분석 할 수 없습니다." + +-#: plugins/copr.py:389 ++#: plugins/copr.py:403 + msgid "Matched: {}" + msgstr "일치하는 항목 : {}" + +-#: plugins/copr.py:394 ++#: plugins/copr.py:408 + msgid "No description given." + msgstr "설명이 없습니다." + +-#: plugins/copr.py:416 ++#: plugins/copr.py:430 + msgid "Safe and good answer. Exiting." + msgstr "안전하고 좋은 대답. 나가기." + +-#: plugins/copr.py:423 ++#: plugins/copr.py:437 + msgid "This command has to be run under the root user." + msgstr "이 명령은 루트 사용자로 실행해야합니다." + +-#: plugins/copr.py:485 ++#: plugins/copr.py:487 ++#, python-brace-format ++msgid "Request to {0} failed: {1} - {2}" ++msgstr "{0}에 대한 요청이 실패함: {1} - {2}" ++ ++#: plugins/copr.py:489 ++msgid "It wasn't possible to enable this project.\n" ++msgstr "이와 같은 프로젝트를 활성화 할 수 없습니다.\n" ++ ++#: plugins/copr.py:494 ++#, python-brace-format ++msgid "Repository '{0}' does not exist in project '{1}'." ++msgstr "저장소 '{0}'는 프로젝트 '{1}'에 존재하지 않습니다." ++ ++#: plugins/copr.py:497 + msgid "" +-"This repository does not have any builds yet so you cannot enable it now." +-msgstr "이 저장소에는 빌드가 아직 없으므로 지금 사용할 수 없습니다." ++"\n" ++"Available repositories: " ++msgstr "" ++"\n" ++"사용 가능한 저장소: " + +-#: plugins/copr.py:488 +-msgid "Such repository does not exist." +-msgstr "이러한 저장소는 존재하지 않습니다." ++#: plugins/copr.py:499 ++#, python-brace-format ++msgid "" ++"\n" ++"\n" ++"If you want to enable a non-default repository, use the following command:\n" ++" 'dnf copr enable {0} '\n" ++"But note that the installed repo file will likely need a manual modification." ++msgstr "" ++"\n" ++"\n" ++"만약 기본설정되지 않은 저장소를 활성화 하고자 한다면, 다음 명령을 사용하세" ++"요: \n" ++" 'dnf copr enable {0} ' \n" ++"하지만 설치된 저장소 파일은 수동으로 수정해야 할 필요가 있다는 점을 참고하세" ++"요." ++ ++#: plugins/copr.py:505 ++#, python-brace-format ++msgid "Project {0} does not exist." ++msgstr "프로젝트 {0}가 존재하지 않습니다." + +-#: plugins/copr.py:532 ++#: plugins/copr.py:508 ++#, python-brace-format ++msgid "Failed to connect to {0}: {1}" ++msgstr "연결 하는데 실패함 {0}: {1}" ++ ++#: plugins/copr.py:555 + #, python-brace-format + msgid "" + "Maintainer of the enabled Copr repository decided to make\n" +@@ -447,50 +494,50 @@ msgstr "" + "\n" + "이들 저장소는 자동으로 활성화 됩니다." + +-#: plugins/copr.py:553 ++#: plugins/copr.py:576 + msgid "Do you want to keep them enabled?" + msgstr "계속 사용하길 원하시나요?" + +-#: plugins/copr.py:586 ++#: plugins/copr.py:609 + #, python-brace-format + msgid "Failed to remove copr repo {0}/{1}/{2}" + msgstr "copr repo {0}/{1}/{2} 제거를 실패하였습니다" + +-#: plugins/copr.py:597 ++#: plugins/copr.py:620 + msgid "Failed to disable copr repo {}/{}" + msgstr "copr repo {} / {}를 사용 중지를 실패하였습니다" + +-#: plugins/copr.py:615 plugins/copr.py:652 ++#: plugins/copr.py:638 plugins/copr.py:675 + msgid "Unknown response from server." + msgstr "서버에서 알 수없는 응답." + +-#: plugins/copr.py:637 ++#: plugins/copr.py:660 + msgid "Interact with Playground repository." + msgstr "놀이터 저장소와 상호 작용하십시오." + +-#: plugins/copr.py:643 ++#: plugins/copr.py:666 + msgid "Enabling a Playground repository." + msgstr "동작 저장소와 활용하기." + +-#: plugins/copr.py:644 ++#: plugins/copr.py:667 + msgid "Do you want to continue?" + msgstr "계속하기를 원하십니까?" + +-#: plugins/copr.py:687 ++#: plugins/copr.py:711 + msgid "Playground repositories successfully enabled." + msgstr "놀이터 저장소를 사용하도록 설정했습니다." + +-#: plugins/copr.py:690 ++#: plugins/copr.py:714 + msgid "Playground repositories successfully disabled." + msgstr "놀이터 저장소가 사용 중지되었습니다." + +-#: plugins/copr.py:694 ++#: plugins/copr.py:718 + msgid "Playground repositories successfully updated." + msgstr "놀이터 저장소가 성공적으로 업데이트되었습니다." + + #: plugins/debug.py:53 + msgid "dump information about installed rpm packages to file" +-msgstr "설치된 rpm 꾸러미(package)에 대한 정보를 파일에 덤프하십시오" ++msgstr "설치된 rpm 꾸러미에 대한 정보를 파일에 덤프하세요" + + #: plugins/debug.py:67 + msgid "do not attempt to dump the repository contents." +@@ -507,7 +554,7 @@ msgstr "작성된 출력 : %s" + + #: plugins/debug.py:172 + msgid "restore packages recorded in debug-dump file" +-msgstr "디버그 덤프 파일에 기록 된 꾸러미(package) 복원" ++msgstr "디버그 덤프 파일에 기록 된 꾸러미 복원" + + #: plugins/debug.py:185 + msgid "output commands that would be run to stdout." +@@ -544,7 +591,7 @@ msgstr "덤프 파일의 이름" + #: plugins/debug.py:273 + #, python-format + msgid "Package %s is not available" +-msgstr "꾸러미(package) %s 사용 할 수 없습니다" ++msgstr "꾸러미 %s를 사용 할 수 없습니다" + + #: plugins/debug.py:283 + #, python-format +@@ -553,39 +600,32 @@ msgstr "잘못된 dnf 디버그 파일 : %s" + + #: plugins/debuginfo-install.py:56 + msgid "install debuginfo packages" +-msgstr "디버그정보 꾸러미(package) 설치" ++msgstr "디버그정보 꾸러미 설치" + + #: plugins/debuginfo-install.py:180 + #, python-format + msgid "" + "Could not find debuginfo package for the following available packages: %s" + msgstr "" +-"다음 사용가능한 꾸러미(package): %s 를 위하여 디버그정보 꾸러미를 찾을 수 없" +-"습니다" ++"다음 사용가능한 꾸러미를 위하여 디버그정보 꾸러미를 찾을 수 없습니다: %s" + + #: plugins/debuginfo-install.py:185 + #, python-format + msgid "" + "Could not find debugsource package for the following available packages: %s" +-msgstr "" +-"다음 가용한 꾸러미(package): %s 를 위하여 디버그자원 꾸러미(package)를 찾을 " +-"수 없습니다" ++msgstr "다음 가용한 꾸러미: %s 를 위하여 디버그자원 꾸러미를 찾을 수 없습니다" + + #: plugins/debuginfo-install.py:190 + #, python-format + msgid "" + "Could not find debuginfo package for the following installed packages: %s" +-msgstr "" +-"다음 설치된 꾸러미(package): %s 를 위한 디버그정보 꾸러미(package)를 찾을 수 " +-"없습니다" ++msgstr "다음 설치된 꾸러미를 위한 디버그정보 꾸러미를 찾을 수 없습니다: %s" + + #: plugins/debuginfo-install.py:195 + #, python-format + msgid "" + "Could not find debugsource package for the following installed packages: %s" +-msgstr "" +-"다음 설치된 꾸러미(package): %s 를 위하여 디버그자원 꾸러미(package)를 찾을 " +-"수 없습니다" ++msgstr "다음 설치된 꾸러미: %s 를 위하여 디버그자원 꾸러미를 찾을 수 없습니다" + + #: plugins/debuginfo-install.py:199 + msgid "Unable to find a match" +@@ -605,15 +645,15 @@ msgstr "대신 src.rpm을 내려받으세요" + + #: plugins/download.py:55 + msgid "download the -debuginfo package instead" +-msgstr "대신 -debuginfo 꾸러미(package)를 내려받아요" ++msgstr "대신 -debuginfo 꾸러미를 내려받아요" + + #: plugins/download.py:57 + msgid "download the -debugsource package instead" +-msgstr "대신 -debuginfo 꾸러미(package)를 내려받으세요" ++msgstr "대신 -debuginfo 꾸러미를 내려받으세요" + + #: plugins/download.py:60 + msgid "limit the query to packages of given architectures." +-msgstr "요청를 주어진 구조 꾸러미(package)로 제한하십시오." ++msgstr "요청를 제공된 구조의 꾸러미로 제한합니다." + + #: plugins/download.py:62 plugins/modulesync.py:51 + msgid "resolve and download needed dependencies" +@@ -647,17 +687,17 @@ msgstr "엄격한 설정으로 인해 종료됩니다." + + #: plugins/download.py:261 + msgid "Error in resolve of packages:" +-msgstr "꾸러미(package) 해결 오류 :" ++msgstr "꾸러미 해결 오류 :" + + #: plugins/download.py:279 + #, python-format + msgid "No source rpm defined for %s" +-msgstr "소스 rpm이 정의되지 않았습니다. %s" ++msgstr "%s를 위한 원천 rpm이 정의되지 않음" + + #: plugins/download.py:296 plugins/download.py:309 + #, python-format + msgid "No package %s available." +-msgstr "가용한 꾸러미(package) %s가 없습니다." ++msgstr "가용한 꾸러미 %s가 없습니다." + + #: plugins/groups_manager.py:49 + msgid "Invalid group id" +@@ -679,7 +719,7 @@ msgstr "" + + #: plugins/groups_manager.py:79 + msgid "create and edit groups metadata file" +-msgstr "그룹 메타데이타 파일 생성하고 수정합니다" ++msgstr "그룹 메타자료 파일을 생성하고 수정합니다" + + #: plugins/groups_manager.py:90 + msgid "load groups metadata from file" +@@ -695,7 +735,7 @@ msgstr "그룹 메타파일을 파일에 적재하고 저장합니다" + + #: plugins/groups_manager.py:97 + msgid "print the result metadata to stdout" +-msgstr "결과 메타데이타를 표준출력으로 출력한다" ++msgstr "결과 메타자료를 표준출력에 출력합니다" + + #: plugins/groups_manager.py:100 + msgid "group id" +@@ -731,23 +771,23 @@ msgstr "그룹 사용자를 보이지 않게 표시" + + #: plugins/groups_manager.py:123 + msgid "add packages to the mandatory section" +-msgstr "꾸러미(package)를 필 수 부분에 추가합니다" ++msgstr "꾸러미를 필수 부분에 추가합니다" + + #: plugins/groups_manager.py:125 + msgid "add packages to the optional section" +-msgstr "꾸러미(package)를 선택 부분에 추가합니다" ++msgstr "꾸러미를 선택 부분에 추가합니다" + + #: plugins/groups_manager.py:127 + msgid "remove packages from the group instead of adding them" +-msgstr "추가하기 대신에 그룹에서 꾸러미(package)를 제거합니다" ++msgstr "추가하기 대신에 그룹에서 꾸러미를 제거합니다" + + #: plugins/groups_manager.py:129 + msgid "include also direct dependencies for packages" +-msgstr "꾸러미(package)를 위해 직접적인 의존성을 포함한다" ++msgstr "꾸러미를 위해 직접적인 의존성을 포함한다" + + #: plugins/groups_manager.py:132 + msgid "package specification" +-msgstr "꾸러미(package) 사양" ++msgstr "꾸러미 사양" + + #: plugins/groups_manager.py:156 + msgid "Can't edit group without specifying it (use --id or --name)" +@@ -767,7 +807,7 @@ msgstr "일치하는 인수가 없습니다 :{}" + + #: plugins/groups_manager.py:298 + msgid "Can't remove packages from non-existent group" +-msgstr "존재하지 않는 그룹에서 꾸러미(package)를 제거 할 수 없습니다" ++msgstr "존재하지 않는 그룹에서 꾸러미를 제거 할 수 없습니다" + + #: plugins/groups_manager.py:307 + msgid "" +@@ -779,7 +819,7 @@ msgstr "" + + #: plugins/leaves.py:32 + msgid "List installed packages not required by any other package" +-msgstr "다른 꾸러미(package)에서 필요하지 않은 설치된 꾸러미(packages) 나열" ++msgstr "다른 꾸러미에서 필요하지 않은 설치된 꾸러미 나열" + + #: plugins/local.py:122 + msgid "Unable to create a directory '{}' due to '{}'" +@@ -812,23 +852,24 @@ msgstr "기록 데이터 마이그레이션 중 ..." + #: plugins/modulesync.py:37 + msgid "" + "Download packages from modules and/or create a repository with modular data" +-msgstr "모듈에서 꾸러미를 내려 받기와/또는 모듈식 자료를 갖고 있는 저장소를 생성" ++msgstr "" ++"모듈에서 꾸러미를 내려 받기와/또는 모듈식 자료를 갖고 있는 저장소를 생성" + + #: plugins/modulesync.py:44 + msgid "MODULE" +-msgstr "모듈" ++msgstr "MODULE" + + #: plugins/modulesync.py:45 + msgid "modules to download" +-msgstr "내려받아야 할 모듈" ++msgstr "내려받기 할 모듈" + + #: plugins/modulesync.py:47 + msgid "enable repositories with source packages" +-msgstr "원천 꾸러미와 함께 저장소를 활성화" ++msgstr "원천 꾸러미로 저장소 활성화" + + #: plugins/modulesync.py:49 + msgid "enable repositories with debug-info and debug-source packages" +-msgstr "디버그-정보와 디버그-원천 꾸러미와 함께 저장소 활성화" ++msgstr "debug-info와 debug-source 꾸러미로 저장소 활성화" + + #: plugins/modulesync.py:53 + msgid "download only packages from newest modules" +@@ -837,28 +878,30 @@ msgstr "최신 모듈에서 꾸러미만 내려받기" + #: plugins/modulesync.py:85 + msgid "Unable to find a match for argument: '{}'" + msgid_plural "Unable to find a match for arguments: '{}'" +-msgstr[0] "인수와 일치하는 항목을 찾을 수 없습니다: '{}'" ++msgstr[0] "인수와 일치 항목을 찾을 수 없음: '{}'" + + #: plugins/modulesync.py:107 + msgid "" + "Creation of repository failed with return code {}. All downloaded content " + "was kept on the system" +-msgstr "반환 코드 {}로 인하여 저장소 생성에 실패함. 모두 내려받기된 내용은 " +-"시스템에서 보관됩니다" ++msgstr "" ++"반환 코드 {}로 인하여 저장소 생성에 실패함. 모두 내려받기된 내용은 시스템에" ++"서 보관됩니다" + + #: plugins/modulesync.py:144 + #, python-brace-format + msgid "No match for artifact '{0}' from module '{1}'" +-msgstr "모듈 '{1}'에서 인위 결과물 '{0}'과 일치하는 부분이 없습니다" ++msgstr "모듈 '{1}' 에서 인위 결과물 '{0}'과 일치하는 부분이 없습니다" + + #: plugins/modulesync.py:162 + #, python-brace-format + msgid "No match for package name '{0}' in profile {1} from module {2}" +-msgstr "모듈 {2}에서 프로파일 {1}인 꾸러미 이름 '{0}'과 일치하는 부분이 없습니다" ++msgstr "" ++"모듈 {2}에서 프로파일 {1}인 꾸러미 이름 '{0}'과 일치하는 부분이 없습니다" + + #: plugins/modulesync.py:166 + msgid "No mach for argument '{}'" +-msgstr "인수와 일치하는 항목이 없습니다 '{}'" ++msgstr "인수 '{}'와 일치하는 항목이 없습니다" + + #. TODO(jmracek) Shell we end with an error or with RC 1? + #: plugins/modulesync.py:198 +@@ -870,8 +913,9 @@ msgstr "필요사항 {}를 만족 할 수 없음" + msgid "" + "No installed package found for package name \"{pkg}\" specified in needs-" + "restarting file \"{file}\"." +-msgstr "재시작이 필요한 파일 \"{file}\" 에 지정한 꾸러미 이름 \"{pkg}\"을 위하여 " +-"설치된 꾸러미를 찾을 수 없습니다." ++msgstr "" ++"재시작이 필요한 파일 \"{file}\" 에 지정한 꾸러미 이름 \"{pkg}\"을 위하여 설치" ++"된 꾸러미를 찾을 수 없습니다." + + #: plugins/needs_restarting.py:220 + msgid "determine updated binaries that need restarting" +@@ -917,18 +961,18 @@ msgid "Bad Action Line \"%s\": %s" + msgstr "잘못된 동작 선 \"%s\": %s" + + #. unsupported state, skip it +-#: plugins/post-transaction-actions.py:130 ++#: plugins/post-transaction-actions.py:133 + #, python-format + msgid "Bad Transaction State: %s" + msgstr "잘못된 연결 상태: %s" + +-#: plugins/post-transaction-actions.py:157 +-#: plugins/post-transaction-actions.py:159 ++#: plugins/post-transaction-actions.py:160 ++#: plugins/post-transaction-actions.py:162 + #, python-format + msgid "post-transaction-actions: %s" + msgstr "연결 후 동작: %s" + +-#: plugins/post-transaction-actions.py:161 ++#: plugins/post-transaction-actions.py:164 + #, python-format + msgid "post-transaction-actions: Bad Command \"%s\": %s" + msgstr "연결 후 동작: 잘못된 명령 \"%s\": %s" +@@ -943,7 +987,7 @@ msgstr "재구 축은 해결되지 않은 종속성으로 종료되었습니다. + + #: plugins/repoclosure.py:153 + msgid "check packages of the given archs, can be specified multiple times" +-msgstr "지정된 아치의 꾸러미(package)를 검사하고 여러 번 지정할 수 있습니다" ++msgstr "지정된 아치의 꾸러미를 검사하고 여러 번 지정할 수 있습니다" + + #: plugins/repoclosure.py:156 + msgid "Specify repositories to check" +@@ -951,11 +995,11 @@ msgstr "점검 할 저장소를 지정하세요" + + #: plugins/repoclosure.py:158 + msgid "Check only the newest packages in the repos" +-msgstr "저장소 최신 꾸러미(package)만 확인하세요" ++msgstr "저장소 최신 꾸러미만 확인하세요" + + #: plugins/repoclosure.py:161 + msgid "Check closure for this package only" +-msgstr "이 꾸러미(package)의 폐쇄만 확인하세요" ++msgstr "이 꾸러미의 폐쇄만 확인하세요" + + #: plugins/repodiff.py:45 + msgid "List differences between two sets of repositories" +@@ -985,12 +1029,12 @@ msgstr "크기 변화에 대한 추가 자료를 출력합니다." + msgid "" + "Compare packages also by arch. By default packages are compared just by name." + msgstr "" +-"구조에 의해 꾸러미(package) 또한 비교합니다. 기본적으로 꾸러미(package)는 이" +-"름으로만 비교됩니다." ++"구조에 의해 꾸러미 또한 비교합니다. 기본적으로 꾸러미는 이름으로만 비교됩니" ++"다." + + #: plugins/repodiff.py:72 + msgid "Output a simple one line message for modified packages." +-msgstr "수정된 꾸러미(pacakage)지를 위해 단순히 한 줄 메시지를 출력합니다." ++msgstr "수정된 꾸러미를 위해 단순히 한 줄 메시지를 출력합니다." + + #: plugins/repodiff.py:74 + msgid "" +@@ -1008,11 +1052,11 @@ msgstr "크기 변화: {} bytes" + + #: plugins/repodiff.py:184 + msgid "Added package : {}" +-msgstr "추가된 꾸러미(package) : {}" ++msgstr "추가된 꾸러미 : {}" + + #: plugins/repodiff.py:187 + msgid "Removed package: {}" +-msgstr "제거된 꾸러미(package): {}" ++msgstr "제거된 꾸러미: {}" + + #: plugins/repodiff.py:190 + msgid "Obsoleted by : {}" +@@ -1024,7 +1068,7 @@ msgid "" + "Upgraded packages" + msgstr "" + "\n" +-"향상된 꾸러미(package)" ++"향상된 꾸러미" + + #: plugins/repodiff.py:200 + msgid "" +@@ -1040,7 +1084,7 @@ msgid "" + "Modified packages" + msgstr "" + "\n" +-"변형된 꾸러미(package)" ++"변형된 꾸러미" + + #: plugins/repodiff.py:212 + msgid "" +@@ -1052,35 +1096,35 @@ msgstr "" + + #: plugins/repodiff.py:213 + msgid "Added packages: {}" +-msgstr "추가된 꾸러미(package): {}" ++msgstr "추가된 꾸러미: {}" + + #: plugins/repodiff.py:214 + msgid "Removed packages: {}" +-msgstr "제거된 꾸러미(package): {}" ++msgstr "제거된 꾸러미: {}" + + #: plugins/repodiff.py:216 + msgid "Upgraded packages: {}" +-msgstr "향상된 꾸러미(package): {}" ++msgstr "향상된 꾸러미: {}" + + #: plugins/repodiff.py:217 + msgid "Downgraded packages: {}" +-msgstr "하향설치된 꾸러미: {}" ++msgstr "하향 설치된 꾸러미: {}" + + #: plugins/repodiff.py:219 + msgid "Modified packages: {}" +-msgstr "변형된 꾸러미(package): {}" ++msgstr "변형된 꾸러미: {}" + + #: plugins/repodiff.py:222 + msgid "Size of added packages: {}" +-msgstr "크기가 증가된 꾸러미(package): {}" ++msgstr "크기가 증가된 꾸러미: {}" + + #: plugins/repodiff.py:223 + msgid "Size of removed packages: {}" +-msgstr "크기가 제거된 꾸러미(package): {}" ++msgstr "크기가 제거된 꾸러미: {}" + + #: plugins/repodiff.py:225 + msgid "Size of modified packages: {}" +-msgstr "크기가 변형된 꾸러미(package): {}" ++msgstr "크기가 변형된 꾸러미: {}" + + #: plugins/repodiff.py:228 + msgid "Size of upgraded packages: {}" +@@ -1096,7 +1140,7 @@ msgstr "크기 변경: {}" + + #: plugins/repograph.py:50 + msgid "Output a full package dependency graph in dot format" +-msgstr "도트 형식의 전체 꾸러미(package) 종속성 그래프 출력" ++msgstr "도트 형식의 전체 꾸러미 종속성 그래프 출력" + + #: plugins/repograph.py:110 + #, python-format +@@ -1105,43 +1149,55 @@ msgstr "아무것도 제공하지 않습니다 : '%s'" + + #: plugins/repomanage.py:45 + msgid "Manage a directory of rpm packages" +-msgstr "rpm 꾸러미(package) 디렉토리 관리" ++msgstr "rpm 꾸러미 디렉토리 관리" + + #: plugins/repomanage.py:59 + msgid "Pass either --old or --new, not both!" + msgstr "--old 또는 --new 중 하나를 전달하세요!" + +-#: plugins/repomanage.py:89 ++#: plugins/repomanage.py:61 ++msgid "Pass either --oldonly or --new, not both!" ++msgstr "--oldonly 또는 --new 중 하나를 전달하세요!" ++ ++#: plugins/repomanage.py:63 ++msgid "Pass either --old or --oldonly, not both!" ++msgstr "--old 또는 --oldonly 중 하나를 전달하세요!" ++ ++#: plugins/repomanage.py:100 + msgid "No files to process" + msgstr "처리 할 파일 없음" + +-#: plugins/repomanage.py:96 ++#: plugins/repomanage.py:107 + msgid "Could not open {}" + msgstr "{}을 열 수 없습니다" + +-#: plugins/repomanage.py:180 ++#: plugins/repomanage.py:223 + msgid "Print the older packages" +-msgstr "이전 꾸러미(package) 인쇄" ++msgstr "이전 꾸러미 인쇄" + +-#: plugins/repomanage.py:182 ++#: plugins/repomanage.py:225 ++msgid "Print the older packages. Exclude the newest packages." ++msgstr "이전 꾸러미를 출력합니다. 최신 꾸러미는 제외합니다." ++ ++#: plugins/repomanage.py:227 + msgid "Print the newest packages" +-msgstr "최신 꾸러미(package) 인쇄" ++msgstr "최신 꾸러미 출력" + +-#: plugins/repomanage.py:184 ++#: plugins/repomanage.py:229 + msgid "Space separated output, not newline" + msgstr "공백으로 구분 된 출력이 아닌 개행 문자" + +-#: plugins/repomanage.py:186 ++#: plugins/repomanage.py:231 + msgid "Newest N packages to keep - defaults to 1" +-msgstr "보관할 최신 N 꾸러미(package) - 기본값은 1입니다" ++msgstr "보관하려는 최신 N 꾸러미 - 기본값은 1입니다" + +-#: plugins/repomanage.py:189 ++#: plugins/repomanage.py:234 + msgid "Path to directory" + msgstr "디렉토리 경로" + + #: plugins/reposync.py:55 + msgid "download all packages from remote repo" +-msgstr "원격 저장소에서 모든 꾸러미(package)를 내려받아요" ++msgstr "원격 저장소에서 모든 꾸러미를 내려받아요" + + #: plugins/reposync.py:64 + msgid "download only packages for this ARCH" +@@ -1153,7 +1209,7 @@ msgstr "저장소에 더 이상 존재하지 않는 로컬 꾸러미(package) + + #: plugins/reposync.py:68 + msgid "download all the metadata." +-msgstr "모든 메타데이타 내려받기." ++msgstr "모든 메타자료 내려받기." + + #: plugins/reposync.py:70 + msgid "Remove packages that fail GPG signature checking after downloading" +@@ -1168,8 +1224,8 @@ msgid "" + "where to store downloaded repository metadata. Defaults to the value of --" + "download-path." + msgstr "" +-"내려받은 저장소 메타데이타를 저장하기 위한 장소. --download-path의 값으로 기" +-"본 지정합니다." ++"내려받은 저장소 메타자료를 저장하기 위한 장소. --download-path의 값으로 기본 " ++"지정합니다." + + #: plugins/reposync.py:78 + msgid "download only newest packages per-repo" +@@ -1202,7 +1258,7 @@ msgstr "다중 저장소와 함께 --norepath를 사용 할 수 없습니다" + #: plugins/reposync.py:132 + #, python-format + msgid "Failed to get mirror for metadata: %s" +-msgstr "메타데이타에 대한 연결주소 얻기를 실패하였습니다:%s" ++msgstr "메타자료에 대한 연결주소 얻기를 실패하였습니다:%s" + + #: plugins/reposync.py:149 + msgid "Failed to get mirror for the group file." +@@ -1237,7 +1293,182 @@ msgstr "저장소에 대한 comps.xml %s 저장된" + + #: plugins/show_leaves.py:54 + msgid "New leaves:" +-msgstr "독립 꾸러미(package):" ++msgstr "독립 꾸러미:" ++ ++#. Translators: This string is only used in unit tests. ++#: plugins/system_upgrade.py:45 ++msgid "the color of the sky" ++msgstr "하늘의 색" ++ ++#: plugins/system_upgrade.py:57 ++msgid "Need a --releasever greater than the current system version." ++msgstr "현재 시스템 버전 보다 큰 --releasever가 필요합니다." ++ ++#. Translators: do not change "reboot" here ++#: plugins/system_upgrade.py:59 ++#, python-brace-format ++msgid "" ++"Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++"To remove cached metadata and transaction use 'dnf {command} clean'" ++msgstr "" ++"내려받기 완료! 향상을 시작하려면 'dnf {command} reboot'를 사용하세요.\n" ++"캐쉬된 메타자료와 연결을 제거하려면 'dnf {command} clean'을 사용하세요" ++ ++#: plugins/system_upgrade.py:62 ++msgid "Sorry, you need to use 'download --releasever' instead of '--network'" ++msgstr "죄송합니다, '--network' 대신에 'download --releasever'를 사용해야 합니다" ++ ++#: plugins/system_upgrade.py:71 ++msgid "Reboot turned off, not rebooting." ++msgstr "다시 기동하지 않고, 재시작이 꺼졌습니다." ++ ++#: plugins/system_upgrade.py:122 ++#, python-format ++msgid "Screen blanking can't be disabled: %s" ++msgstr "화면 비우기를 비활성화 할 수 없습니다: %s" ++ ++#: plugins/system_upgrade.py:142 ++#, python-format ++msgid "Failed loading state file: %s, continuing with empty state." ++msgstr "상태 파일: %s를 적재 중 실패함, 공백 상태로 유지됨." ++ ++#: plugins/system_upgrade.py:289 ++msgid "The following boots appear to contain upgrade logs:" ++msgstr "다음 기동은 향상된 기록을 포함하여 나타납니다:" ++ ++#: plugins/system_upgrade.py:299 ++msgid "-- no logs were found --" ++msgstr "-- 어떤 기록도 찾을 수 없음 --" ++ ++#: plugins/system_upgrade.py:314 ++msgid "Cannot find logs with this index." ++msgstr "이 표시가 있는 기록을 찾을 수 없습니다." ++ ++#: plugins/system_upgrade.py:323 ++msgid "Unable to match systemd journal entry" ++msgstr "systemd journal 항목과 일치 할 수 없음" ++ ++#: plugins/system_upgrade.py:344 ++msgid "Prepare system for upgrade to a new release" ++msgstr "새로운 출시로 향상하기 위해 시스템을 준비합니다" ++ ++#: plugins/system_upgrade.py:360 ++msgid "keep installed packages if the new release's version is older" ++msgstr "만약 신규 출시의 버전이 오래되었으면 설치된 꾸러미를 유지합니다" ++ ++#: plugins/system_upgrade.py:364 ++msgid "which logs to show" ++msgstr "표시 할 어떤 기록" ++ ++#: plugins/system_upgrade.py:398 ++#, python-brace-format ++msgid "Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++msgstr "호환되지 않는 자료 버전. 'dnf {command} download [OPTIONS]' 되돌리기" ++ ++#: plugins/system_upgrade.py:434 ++msgid "Command 'offline-distrosync' cannot be used with --no-downgrade option" ++msgstr "명령 'offline-distrosync'은 --no-downgrade 옵션과 함께 사용 될 수 없습니다" ++ ++#: plugins/system_upgrade.py:454 ++msgid "" ++"WARNING: this operation is not supported on the RHEL distribution. Proceed " ++"at your own risk." ++msgstr "경고: 이와 같은 동작은 RHEL 배포판에서 지원되지 않습니다. 자신의 책임 하에 " ++"진행하세요." ++ ++#: plugins/system_upgrade.py:458 ++msgid "Additional information for System Upgrade: {}" ++msgstr "시스템 향상을 위한 추가 정보: {}" ++ ++#: plugins/system_upgrade.py:461 ++msgid "" ++"Before you continue ensure that your system is fully upgraded by running " ++"\"dnf --refresh upgrade\". Do you want to continue" ++msgstr "계속하기 전에 dnf --refresh upgrade\" 실행하여 시스템을 완전히 향상 되도록 " ++"해주세요. 계속 하길 원하세요" ++ ++#: plugins/system_upgrade.py:465 ++msgid "Operation aborted." ++msgstr "작업이 중지됩니다." ++ ++#: plugins/system_upgrade.py:526 ++msgid "system is not ready for upgrade" ++msgstr "시스템이 향상을 위해 준비되지 않았습니다" ++ ++#: plugins/system_upgrade.py:529 ++#, python-brace-format ++msgid "" ++"the transaction was not prepared for '{command}'. Rerun 'dnf {command} " ++"download [OPTIONS]'" ++msgstr "" ++"연결이 '{command}'을 위해 준비되지 않았습니다. 'dnf {command} download " ++"[OPTIONS]'을 되돌립니다" ++ ++#: plugins/system_upgrade.py:533 ++msgid "upgrade is already scheduled" ++msgstr "향상은 이미 계획되어 있습니다" ++ ++#: plugins/system_upgrade.py:539 ++msgid "trigger file does not exist. exiting quietly." ++msgstr "트리거 파일이 존재하지 않습니다. 바로 종료하기." ++ ++#: plugins/system_upgrade.py:542 ++msgid "another upgrade tool is running. exiting quietly." ++msgstr "다른 향상 도구가 동작 중입니다. 바로 종료하기." ++ ++#: plugins/system_upgrade.py:551 ++#, python-brace-format ++msgid "use 'dnf {command} reboot' to begin the upgrade" ++msgstr "'dnf {command} reboot' 사용하여 향상을 시작합니다" ++ ++#: plugins/system_upgrade.py:569 ++msgid "Rebooting to perform upgrade." ++msgstr "향상을 수행하기 위해서 재시작 중." ++ ++#: plugins/system_upgrade.py:602 ++msgid "Starting offline upgrade. This will take a while." ++msgstr "오프라인 향상 시작하기. 이는 시간이 좀 걸립니다." ++ ++#: plugins/system_upgrade.py:604 ++msgid "Starting offline distrosync. This will take a while." ++msgstr "오프라인 distrosync 시작 중. 이는 시간이 좀 걸립니다." ++ ++#: plugins/system_upgrade.py:606 ++msgid "Starting system upgrade. This will take a while." ++msgstr "시스템 향상이 시작 중. 이는 시간이 좀 걸립니다." ++ ++#: plugins/system_upgrade.py:622 ++msgid "Cleaning up downloaded data..." ++msgstr "내려받기된 자료를 정리 중..." ++ ++#: plugins/system_upgrade.py:652 ++msgid "" ++"The system-upgrade transaction is empty, your system is already up-to-date." ++msgstr "시스템-향상 연결이 비워 있으며, 시스템은 이미 최신화 되었습니다." ++ ++#: plugins/system_upgrade.py:661 ++msgid "Transaction saved to {}." ++msgstr "연결이 {}로 저장되었습니다." ++ ++#: plugins/system_upgrade.py:664 ++msgid "Error storing transaction: {}" ++msgstr "저장 중 연결 오류: {}" ++ ++#: plugins/system_upgrade.py:686 ++msgid "Download finished." ++msgstr "내려받기 완료됨." ++ ++#: plugins/system_upgrade.py:689 plugins/system_upgrade.py:690 ++msgid "Upgrade complete! Cleaning up and rebooting..." ++msgstr "향상 성공! 정리하고 재시작하기..." ++ ++#: plugins/system_upgrade.py:699 ++msgid "Prepare offline upgrade of the system" ++msgstr "시스템의 오프라인 향상을 준비합니다" ++ ++#: plugins/system_upgrade.py:704 ++msgid "Prepare offline distrosync of the system" ++msgstr "시스템의 오프라인 distrosync를 준비합니다" + + #: plugins/versionlock.py:33 + #, python-format +@@ -1303,8 +1534,13 @@ msgstr "꾸러미(package) 사양을 그대로 사용하며, 구문 분석을 + + #: plugins/versionlock.py:160 + msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." +-msgstr "하위명령 '{}'는 더 이상 사용하지 않습니다. 대신에 하위명령 'exclude'를 " +-"사용합니다." ++msgstr "" ++"하위명령 '{}'는 더 이상 사용하지 않습니다. 대신에 하위명령 'exclude'를 사용합" ++"니다." ++ ++#~ msgid "" ++#~ "This repository does not have any builds yet so you cannot enable it now." ++#~ msgstr "이 저장소에는 빌드가 아직 없으므로 지금 사용할 수 없습니다." + + #~ msgid "" + #~ "\n" +diff --git a/po/zh_CN.po b/po/zh_CN.po +index 5e5627e..973d486 100644 +--- a/po/zh_CN.po ++++ b/po/zh_CN.po +@@ -7,13 +7,13 @@ + # Hongqiao Chen , 2020. + # Sundeep Anand , 2021. + # Qiyu Yan , 2021. +-# Transtats , 2022. ++# Transtats , 2022, 2023. + msgid "" + msgstr "" + "Project-Id-Version: PACKAGE VERSION\n" + "Report-Msgid-Bugs-To: \n" +-"POT-Creation-Date: 2022-02-28 11:53+0100\n" +-"PO-Revision-Date: 2022-03-09 12:39+0000\n" ++"POT-Creation-Date: 2023-02-28 12:21+0100\n" ++"PO-Revision-Date: 2023-03-06 13:48+0000\n" + "Last-Translator: Transtats \n" + "Language-Team: Chinese (Simplified) \n" +@@ -22,7 +22,7 @@ msgstr "" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=1; plural=0;\n" +-"X-Generator: Weblate 4.11.2\n" ++"X-Generator: Weblate 4.15.2\n" + + #: plugins/builddep.py:45 + msgid "[PACKAGE|PACKAGE.spec]" +@@ -73,16 +73,21 @@ msgstr "没有匹配的软件包可以安装: '%s'" + msgid "Failed to open: '%s', not a valid source rpm file." + msgstr "打开文件失败: '%s',不是有效的源码 RPM 文件。" + +-#: plugins/builddep.py:204 plugins/builddep.py:220 plugins/builddep.py:237 ++#: plugins/builddep.py:204 plugins/builddep.py:224 plugins/builddep.py:241 + msgid "Not all dependencies satisfied" + msgstr "没有满足全部的依赖关系" + +-#: plugins/builddep.py:211 ++#: plugins/builddep.py:208 ++msgid "" ++"Warning: -D or --define arguments have no meaning for source rpm packages." ++msgstr "警告:-D 或 --define 参数对源 rpm 软件包没有意义。" ++ ++#: plugins/builddep.py:215 + #, python-format + msgid "Failed to open: '%s', not a valid spec file: %s" + msgstr "打开失败: '%s', 不是有效的 spec 文件: %s" + +-#: plugins/builddep.py:230 plugins/repoclosure.py:118 ++#: plugins/builddep.py:234 plugins/repoclosure.py:118 + #, python-format + msgid "no package matched: %s" + msgstr "无匹配软件包: %s" +@@ -208,27 +213,27 @@ msgstr[0] "配置仓库失败" + msgid "Could not save repo to repofile %s: %s" + msgstr "无法保存仓库至仓库文件 %s:%s" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "y" + msgstr "y" + +-#: plugins/copr.py:64 ++#: plugins/copr.py:70 + msgid "yes" + msgstr "是" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "n" + msgstr "n" + +-#: plugins/copr.py:65 ++#: plugins/copr.py:71 + msgid "no" + msgstr "否" + +-#: plugins/copr.py:84 ++#: plugins/copr.py:92 + msgid "Interact with Copr repositories." + msgstr "与 Copr 仓库交互。" + +-#: plugins/copr.py:86 ++#: plugins/copr.py:94 + msgid "" + "\n" + " enable name/project [chroot]\n" +@@ -266,31 +271,31 @@ msgstr "" + " copr search tests\n" + " " + +-#: plugins/copr.py:112 ++#: plugins/copr.py:120 + msgid "List all installed Copr repositories (default)" + msgstr "列出所有安装的 Copr 仓库(默认)" + +-#: plugins/copr.py:114 ++#: plugins/copr.py:122 + msgid "List enabled Copr repositories" + msgstr "列出启动的 Copr 仓库" + +-#: plugins/copr.py:116 ++#: plugins/copr.py:124 + msgid "List disabled Copr repositories" + msgstr "列出禁用的 Copr 仓库" + +-#: plugins/copr.py:118 ++#: plugins/copr.py:126 + msgid "List available Copr repositories by user NAME" + msgstr "按照用户 NAME 列出可用的 Copr 仓库" + +-#: plugins/copr.py:120 ++#: plugins/copr.py:128 + msgid "Specify an instance of Copr to work with" + msgstr "指定需要使用的 Copr 实例" + +-#: plugins/copr.py:154 plugins/copr.py:222 plugins/copr.py:249 ++#: plugins/copr.py:164 plugins/copr.py:236 plugins/copr.py:263 + msgid "Error: " + msgstr "错误: " + +-#: plugins/copr.py:155 ++#: plugins/copr.py:165 + msgid "" + "specify Copr hub either with `--hub` or using `copr_hub/copr_username/" + "copr_projectname` format" +@@ -298,33 +303,33 @@ msgstr "" + "使用 `--hub` 或使用 `copr_hub/copr_username/copr_projectname` 格式指定 Copr " + "hub" + +-#: plugins/copr.py:158 ++#: plugins/copr.py:168 + msgid "multiple hubs specified" + msgstr "指定多个 hub" + +-#: plugins/copr.py:223 plugins/copr.py:227 ++#: plugins/copr.py:237 plugins/copr.py:241 + msgid "exactly two additional parameters to copr command are required" + msgstr "Copr 命令要求有且仅有两个额外参数" + +-#: plugins/copr.py:232 ++#: plugins/copr.py:246 + msgid "Too many arguments." + msgstr "参数过多。" + +-#: plugins/copr.py:235 ++#: plugins/copr.py:249 + msgid "" + "Bad format of optional chroot. The format is distribution-version-" + "architecture." + msgstr "可选 chroot 的错误格式。格式为 distribution-version-architecture。" + +-#: plugins/copr.py:250 ++#: plugins/copr.py:264 + msgid "use format `copr_username/copr_projectname` to reference copr project" + msgstr "使用格式 `copr_username/copr_projectname` 来引用 Copr 项目" + +-#: plugins/copr.py:252 ++#: plugins/copr.py:266 + msgid "bad copr project format" + msgstr "错误的 Copr 项目格式" + +-#: plugins/copr.py:266 ++#: plugins/copr.py:280 + msgid "" + "\n" + "Enabling a Copr repository. Please note that this repository is not part\n" +@@ -352,23 +357,23 @@ msgstr "" + "请不要在 Fedora Bugzilla 中报告这些软件包中出现的\n" + "问题。当出现问题时,请联系仓库的所有者。\n" + +-#: plugins/copr.py:283 ++#: plugins/copr.py:297 + msgid "Repository successfully enabled." + msgstr "启用软件仓库成功。" + +-#: plugins/copr.py:288 ++#: plugins/copr.py:302 + msgid "Repository successfully disabled." + msgstr "禁用软件仓库成功。" + +-#: plugins/copr.py:292 ++#: plugins/copr.py:306 + msgid "Repository successfully removed." + msgstr "软件仓库已成功删除。" + +-#: plugins/copr.py:296 plugins/copr.py:697 ++#: plugins/copr.py:310 plugins/copr.py:721 + msgid "Unknown subcommand {}." + msgstr "未知的子命令 {}。" + +-#: plugins/copr.py:353 ++#: plugins/copr.py:367 + msgid "" + "* These coprs have repo file with an old format that contains no information " + "about Copr hub - the default one was assumed. Re-enable the project to fix " +@@ -377,48 +382,86 @@ msgstr "" + "* 这些 coprs 有使用旧格式的 repo 文件,它们没有包括 Copr hub 的信息 - 假设使" + "用默认值。重新启用项目来解决这个问题。" + +-#: plugins/copr.py:366 ++#: plugins/copr.py:380 + msgid "Can't parse repositories for username '{}'." + msgstr "无法为用户名 username '{}' 解析仓库。" + +-#: plugins/copr.py:369 ++#: plugins/copr.py:383 + msgid "List of {} coprs" + msgstr "{} Coprs 列表" + +-#: plugins/copr.py:374 ++#: plugins/copr.py:388 + msgid "No description given" + msgstr "没有给出描述" + +-#: plugins/copr.py:386 ++#: plugins/copr.py:400 + msgid "Can't parse search for '{}'." + msgstr "无法解析针对 '{}' 的搜索。" + +-#: plugins/copr.py:389 ++#: plugins/copr.py:403 + msgid "Matched: {}" + msgstr "匹配:{}" + +-#: plugins/copr.py:394 ++#: plugins/copr.py:408 + msgid "No description given." + msgstr "没有给出描述。" + +-#: plugins/copr.py:416 ++#: plugins/copr.py:430 + msgid "Safe and good answer. Exiting." + msgstr "安全及明智的答案。退出。" + +-#: plugins/copr.py:423 ++#: plugins/copr.py:437 + msgid "This command has to be run under the root user." + msgstr "该命令必须以 root 用户运行。" + +-#: plugins/copr.py:485 ++#: plugins/copr.py:487 ++#, python-brace-format ++msgid "Request to {0} failed: {1} - {2}" ++msgstr "请求 {0} 失败:{1} - {2}" ++ ++#: plugins/copr.py:489 ++msgid "It wasn't possible to enable this project.\n" ++msgstr "无法启用此项目。\n" ++ ++#: plugins/copr.py:494 ++#, python-brace-format ++msgid "Repository '{0}' does not exist in project '{1}'." ++msgstr "仓库 '{0}' 在项目 '{1}' 中不存在。" ++ ++#: plugins/copr.py:497 + msgid "" +-"This repository does not have any builds yet so you cannot enable it now." +-msgstr "该仓库尚未包含任何构建所以您现在无法启用它。" ++"\n" ++"Available repositories: " ++msgstr "" ++"\n" ++"可用软件仓库: " + +-#: plugins/copr.py:488 +-msgid "Such repository does not exist." +-msgstr "该软件仓库不存在。" ++#: plugins/copr.py:499 ++#, python-brace-format ++msgid "" ++"\n" ++"\n" ++"If you want to enable a non-default repository, use the following command:\n" ++" 'dnf copr enable {0} '\n" ++"But note that the installed repo file will likely need a manual modification." ++msgstr "" ++"\n" ++"\n" ++"如果需要启用一个非默认的仓库,使用以下命令 :\n" ++" 'dnf copr enable {0} '\n" ++"但请注意,安装的 repo 文件将来可能需要手动修改。" + +-#: plugins/copr.py:532 ++#: plugins/copr.py:505 ++#, python-brace-format ++msgid "Project {0} does not exist." ++msgstr "项目 {0} 不存在。" ++ ++#: plugins/copr.py:508 ++#, python-brace-format ++msgid "Failed to connect to {0}: {1}" ++msgstr "连接到 {0} 失败:{1}" ++ ++#: plugins/copr.py:555 + #, python-brace-format + msgid "" + "Maintainer of the enabled Copr repository decided to make\n" +@@ -447,44 +490,44 @@ msgstr "" + "\n" + "这些仓库已被自动启用。" + +-#: plugins/copr.py:553 ++#: plugins/copr.py:576 + msgid "Do you want to keep them enabled?" + msgstr "您需要保持它们被启用吗?" + +-#: plugins/copr.py:586 ++#: plugins/copr.py:609 + #, python-brace-format + msgid "Failed to remove copr repo {0}/{1}/{2}" +-msgstr "删除 copr 仓库 {0}/{1}/{2} 失败" ++msgstr "无法删除 copr 存储库 {0}/{1}/{2}" + +-#: plugins/copr.py:597 ++#: plugins/copr.py:620 + msgid "Failed to disable copr repo {}/{}" +-msgstr "无法禁用 Copr 软件仓库 {}/{}" ++msgstr "无法禁用 Copr 存储库 {}/{}" + +-#: plugins/copr.py:615 plugins/copr.py:652 ++#: plugins/copr.py:638 plugins/copr.py:675 + msgid "Unknown response from server." + msgstr "来自服务器的未知响应。" + +-#: plugins/copr.py:637 ++#: plugins/copr.py:660 + msgid "Interact with Playground repository." + msgstr "与 Playground 仓库交互。" + +-#: plugins/copr.py:643 ++#: plugins/copr.py:666 + msgid "Enabling a Playground repository." + msgstr "启用 Playground 仓库。" + +-#: plugins/copr.py:644 ++#: plugins/copr.py:667 + msgid "Do you want to continue?" + msgstr "您希望继续吗?" + +-#: plugins/copr.py:687 ++#: plugins/copr.py:711 + msgid "Playground repositories successfully enabled." + msgstr "启用 Playground 仓库成功。" + +-#: plugins/copr.py:690 ++#: plugins/copr.py:714 + msgid "Playground repositories successfully disabled." + msgstr "禁用 Playground 仓库成功。" + +-#: plugins/copr.py:694 ++#: plugins/copr.py:718 + msgid "Playground repositories successfully updated." + msgstr "更新 Playground 仓库成功。" + +@@ -737,7 +780,7 @@ msgstr "软件包规格" + + #: plugins/groups_manager.py:156 + msgid "Can't edit group without specifying it (use --id or --name)" +-msgstr "没有指定组(使用 --id 或 --name)就无法编辑组" ++msgstr "没有指定它(使用 --id 或 --name)就不能编辑组" + + #: plugins/groups_manager.py:190 + msgid "Can't load file \"{}\": {}" +@@ -791,7 +834,7 @@ msgstr "迁移 yum 的历史、分组以及 yumdb 数据至 dnf" + + #: plugins/migrate.py:54 + msgid "Migrating history data..." +-msgstr "正在迁移历史数据…" ++msgstr "正在迁移历史数据..." + + #: plugins/modulesync.py:37 + msgid "" +@@ -821,7 +864,7 @@ msgstr "只从最新的模块中下载软件包" + #: plugins/modulesync.py:85 + msgid "Unable to find a match for argument: '{}'" + msgid_plural "Unable to find a match for arguments: '{}'" +-msgstr[0] "找不到与参数:'{}'相匹配的项" ++msgstr[0] "找不到与参数匹配的项:'{}'" + + #: plugins/modulesync.py:107 + msgid "" +@@ -832,12 +875,12 @@ msgstr "创建存储库会失败,并显示返回码 {}。所有下载的内容 + #: plugins/modulesync.py:144 + #, python-brace-format + msgid "No match for artifact '{0}' from module '{1}'" +-msgstr "没有与模块 '{1}' 的工件 '{0}' 相匹配的项" ++msgstr "没有与来自模块 '{1}' 的工件 '{0}' 相匹配的项" + + #: plugins/modulesync.py:162 + #, python-brace-format + msgid "No match for package name '{0}' in profile {1} from module {2}" +-msgstr "没有与模块 {2} 中配置文件 {1} 的软件包名称 '{0}' 相匹配的项" ++msgstr "没有与来自模块 {2} 中配置集 {1} 的软件包名称 '{0}' 相匹配的项" + + #: plugins/modulesync.py:166 + msgid "No mach for argument '{}'" +@@ -853,8 +896,9 @@ msgstr "无法满足要求 {}" + msgid "" + "No installed package found for package name \"{pkg}\" specified in needs-" + "restarting file \"{file}\"." +-msgstr "未找到在需要重新启动文件 \"{file}\" 中指定的软件包名为 \"{pkg}\" " +-"的已安装的软件包。" ++msgstr "" ++"未找到在需要重新启动的文件 \"{file}\" 中指定的软件包名为 \"{pkg}\" 的已安装的" ++"软件包。" + + #: plugins/needs_restarting.py:220 + msgid "determine updated binaries that need restarting" +@@ -899,18 +943,18 @@ msgid "Bad Action Line \"%s\": %s" + msgstr "错误的操作行“ %s”: %s" + + #. unsupported state, skip it +-#: plugins/post-transaction-actions.py:130 ++#: plugins/post-transaction-actions.py:133 + #, python-format + msgid "Bad Transaction State: %s" + msgstr "错误的事务状态: %s" + +-#: plugins/post-transaction-actions.py:157 +-#: plugins/post-transaction-actions.py:159 ++#: plugins/post-transaction-actions.py:160 ++#: plugins/post-transaction-actions.py:162 + #, python-format + msgid "post-transaction-actions: %s" + msgstr "事物后的操作: %s" + +-#: plugins/post-transaction-actions.py:161 ++#: plugins/post-transaction-actions.py:164 + #, python-format + msgid "post-transaction-actions: Bad Command \"%s\": %s" + msgstr "事物后的操作 : 无效的命令 \"%s\": %s" +@@ -1087,33 +1131,45 @@ msgstr "管理 RPM 软件包目录" + + #: plugins/repomanage.py:59 + msgid "Pass either --old or --new, not both!" +-msgstr "传入 --old 或者 --new,不可同时传入!" ++msgstr "传递 --old 或者 --new,而不是两者都传递!" + +-#: plugins/repomanage.py:89 ++#: plugins/repomanage.py:61 ++msgid "Pass either --oldonly or --new, not both!" ++msgstr "传递 --oldonly 或 --new,而不是两者都传递!" ++ ++#: plugins/repomanage.py:63 ++msgid "Pass either --old or --oldonly, not both!" ++msgstr "传递 --old 或 --oldonly,而不是两者都传递!" ++ ++#: plugins/repomanage.py:100 + msgid "No files to process" + msgstr "没有可处理的文件" + +-#: plugins/repomanage.py:96 ++#: plugins/repomanage.py:107 + msgid "Could not open {}" + msgstr "无法打开 {}" + +-#: plugins/repomanage.py:180 ++#: plugins/repomanage.py:223 + msgid "Print the older packages" + msgstr "打印较旧的软件包" + +-#: plugins/repomanage.py:182 ++#: plugins/repomanage.py:225 ++msgid "Print the older packages. Exclude the newest packages." ++msgstr "打印旧的软件包。排除最新的软件包。" ++ ++#: plugins/repomanage.py:227 + msgid "Print the newest packages" + msgstr "打印最新的软件包" + +-#: plugins/repomanage.py:184 ++#: plugins/repomanage.py:229 + msgid "Space separated output, not newline" + msgstr "用空格分割输出,而不是新行" + +-#: plugins/repomanage.py:186 ++#: plugins/repomanage.py:231 + msgid "Newest N packages to keep - defaults to 1" + msgstr "要保留的最新的 N 个软件包 - 默认值为 1" + +-#: plugins/repomanage.py:189 ++#: plugins/repomanage.py:234 + msgid "Path to directory" + msgstr "指向目录的路径" + +@@ -1215,6 +1271,178 @@ msgstr "仓库 %s 的 comps.xml 已保存" + msgid "New leaves:" + msgstr "新增保留项:" + ++#. Translators: This string is only used in unit tests. ++#: plugins/system_upgrade.py:45 ++msgid "the color of the sky" ++msgstr "sky 的颜色" ++ ++#: plugins/system_upgrade.py:57 ++msgid "Need a --releasever greater than the current system version." ++msgstr "需要大于当前系统版本的 --releasever。" ++ ++#. Translators: do not change "reboot" here ++#: plugins/system_upgrade.py:59 ++#, python-brace-format ++msgid "" ++"Download complete! Use 'dnf {command} reboot' to start the upgrade.\n" ++"To remove cached metadata and transaction use 'dnf {command} clean'" ++msgstr "" ++"下载完成!使用 'dnf {command} reboot' 启动升级。 \n" ++" 要删除缓存的元数据和事务,请使用 'dnf {command} clean'" ++ ++#: plugins/system_upgrade.py:62 ++msgid "Sorry, you need to use 'download --releasever' instead of '--network'" ++msgstr "您需要使用 'download --releasever' 而不是 '-network'" ++ ++#: plugins/system_upgrade.py:71 ++msgid "Reboot turned off, not rebooting." ++msgstr "重启被关闭,没有重新启动。" ++ ++#: plugins/system_upgrade.py:122 ++#, python-format ++msgid "Screen blanking can't be disabled: %s" ++msgstr "无法禁用屏幕空白:%s" ++ ++#: plugins/system_upgrade.py:142 ++#, python-format ++msgid "Failed loading state file: %s, continuing with empty state." ++msgstr "加载状态文件失败:%s,继续为空状态。" ++ ++#: plugins/system_upgrade.py:289 ++msgid "The following boots appear to contain upgrade logs:" ++msgstr "以下引导会包含升级日志:" ++ ++#: plugins/system_upgrade.py:299 ++msgid "-- no logs were found --" ++msgstr "-- 没有找到日志 --" ++ ++#: plugins/system_upgrade.py:314 ++msgid "Cannot find logs with this index." ++msgstr "无法找到使用此索引的日志。" ++ ++#: plugins/system_upgrade.py:323 ++msgid "Unable to match systemd journal entry" ++msgstr "无法与 systemd 日志条目匹配" ++ ++#: plugins/system_upgrade.py:344 ++msgid "Prepare system for upgrade to a new release" ++msgstr "准备系统以升级到新版本" ++ ++#: plugins/system_upgrade.py:360 ++msgid "keep installed packages if the new release's version is older" ++msgstr "如果新版本中的版本更旧,保留安装的软件包" ++ ++#: plugins/system_upgrade.py:364 ++msgid "which logs to show" ++msgstr "要显示的日志" ++ ++#: plugins/system_upgrade.py:398 ++#, python-brace-format ++msgid "Incompatible version of data. Rerun 'dnf {command} download [OPTIONS]'" ++msgstr "不兼容的数据版本。重新运行 'dnf {command} download [OPTIONS]'" ++ ++#: plugins/system_upgrade.py:434 ++msgid "Command 'offline-distrosync' cannot be used with --no-downgrade option" ++msgstr "命令 'offline-distrosync' 无法与 --no-downgrade 选项一起使用" ++ ++#: plugins/system_upgrade.py:454 ++msgid "" ++"WARNING: this operation is not supported on the RHEL distribution. Proceed " ++"at your own risk." ++msgstr "警告:在 RHEL 发行版上不支持此操作。您需要自性承担相关的风险。" ++ ++#: plugins/system_upgrade.py:458 ++msgid "Additional information for System Upgrade: {}" ++msgstr "系统升级的额外信息:{}" ++ ++#: plugins/system_upgrade.py:461 ++msgid "" ++"Before you continue ensure that your system is fully upgraded by running " ++"\"dnf --refresh upgrade\". Do you want to continue" ++msgstr "在继续请,确定您的系统已通过运行 \"dnf --refresh upgrade\" " ++"完全升级。您要继续操作" ++ ++#: plugins/system_upgrade.py:465 ++msgid "Operation aborted." ++msgstr "操作中止。" ++ ++#: plugins/system_upgrade.py:526 ++msgid "system is not ready for upgrade" ++msgstr "系统还未就绪进行升级" ++ ++#: plugins/system_upgrade.py:529 ++#, python-brace-format ++msgid "" ++"the transaction was not prepared for '{command}'. Rerun 'dnf {command} " ++"download [OPTIONS]'" ++msgstr "事务没有为 '{command}' 准备。重新运行 'dnf {command} download [OPTIONS]'" ++ ++#: plugins/system_upgrade.py:533 ++msgid "upgrade is already scheduled" ++msgstr "升级已被调度" ++ ++#: plugins/system_upgrade.py:539 ++msgid "trigger file does not exist. exiting quietly." ++msgstr "触发器文件不存在。静默退出。" ++ ++#: plugins/system_upgrade.py:542 ++msgid "another upgrade tool is running. exiting quietly." ++msgstr "另一个升级工具正在运行。静默退出。" ++ ++#: plugins/system_upgrade.py:551 ++#, python-brace-format ++msgid "use 'dnf {command} reboot' to begin the upgrade" ++msgstr "使用 'dnf {command} reboot' 开始升级" ++ ++#: plugins/system_upgrade.py:569 ++msgid "Rebooting to perform upgrade." ++msgstr "重启以执行升级。" ++ ++#: plugins/system_upgrade.py:602 ++msgid "Starting offline upgrade. This will take a while." ++msgstr "启动离线升级。这将需要一段时间。" ++ ++#: plugins/system_upgrade.py:604 ++msgid "Starting offline distrosync. This will take a while." ++msgstr "启动离线 distrosync。这将需要一段时间。" ++ ++#: plugins/system_upgrade.py:606 ++msgid "Starting system upgrade. This will take a while." ++msgstr "启动系统升级。这需要一段时间。" ++ ++#: plugins/system_upgrade.py:622 ++msgid "Cleaning up downloaded data..." ++msgstr "清理下载的数据..." ++ ++#: plugins/system_upgrade.py:652 ++msgid "" ++"The system-upgrade transaction is empty, your system is already up-to-date." ++msgstr "system-upgrade 事务为空,您的系统已经为最新版本。" ++ ++#: plugins/system_upgrade.py:661 ++msgid "Transaction saved to {}." ++msgstr "事务已保存到 {}。" ++ ++#: plugins/system_upgrade.py:664 ++msgid "Error storing transaction: {}" ++msgstr "存储事务时出现错误:{}" ++ ++#: plugins/system_upgrade.py:686 ++msgid "Download finished." ++msgstr "下载已完成。" ++ ++#: plugins/system_upgrade.py:689 plugins/system_upgrade.py:690 ++msgid "Upgrade complete! Cleaning up and rebooting..." ++msgstr "升级完成!清理并重启..." ++ ++#: plugins/system_upgrade.py:699 ++msgid "Prepare offline upgrade of the system" ++msgstr "准备系统的离线升级" ++ ++#: plugins/system_upgrade.py:704 ++msgid "Prepare offline distrosync of the system" ++msgstr "准备系统的离线 distrosync" ++ + #: plugins/versionlock.py:33 + #, python-format + msgid "Unable to read version lock configuration: %s" +@@ -1281,6 +1509,10 @@ msgstr "按原样使用程序包规格,请勿尝试解析它们" + msgid "Subcommand '{}' is deprecated. Use 'exclude' subcommand instead." + msgstr "子命令 '{}' 已被弃用。改为使用 'exclude' 子命令。" + ++#~ msgid "" ++#~ "This repository does not have any builds yet so you cannot enable it now." ++#~ msgstr "该仓库尚未包含任何构建所以您现在无法启用它。" ++ + #~ msgid "" + #~ "\n" + #~ "You are about to enable a Playground repository.\n" +-- +2.39.2 + diff --git a/SPECS/dnf-plugins-core.spec b/SPECS/dnf-plugins-core.spec index e9128e1..0a5682d 100644 --- a/SPECS/dnf-plugins-core.spec +++ b/SPECS/dnf-plugins-core.spec @@ -34,7 +34,7 @@ Name: dnf-plugins-core Version: 4.0.21 -Release: 14.1%{?dist} +Release: 19%{?dist} Summary: Core Plugins for DNF License: GPLv2+ URL: https://github.com/rpm-software-management/dnf-plugins-core @@ -62,7 +62,12 @@ Patch20: 0020-Shorter-verification-that-the-project-exists.patch Patch21: 0021-Better-error-message-for-dnf-copr-enable.patch Patch22: 0022-copr-allow-specifying-protocol-as-part-of-hub.patch Patch23: 0023-copr-Guess-EPEL-chroots-for-CentOS-Stream-RhBug-2058.patch -Patch24: 0024-Update-translations-RHEL-8.7.patch +Patch24: 0024-builddep-Warning-when-using-macros-with-source-rpms-.patch +Patch25: 0025-Move-system-upgrade-plugin-to-core-RhBug-2054235.patch +Patch26: 0026-Add-a-warning-when-using-system-upgrade-on-RHEL.patch +Patch27: 0027-offline-upgrade-Add-security-filters.patch +Patch28: 0028-system-upgrade-Show-warning-always-for-a-downstream.patch +Patch29: 0029-Update-translations.patch BuildArch: noarch @@ -90,6 +95,9 @@ Provides: dnf-command(repograph) Provides: dnf-command(repomanage) Provides: dnf-command(reposync) Provides: dnf-command(repodiff) +Provides: dnf-command(system-upgrade) +Provides: dnf-command(offline-upgrade) +Provides: dnf-command(offline-distrosync) Provides: dnf-plugins-extras-debug = %{version}-%{release} Provides: dnf-plugins-extras-repoclosure = %{version}-%{release} Provides: dnf-plugins-extras-repograph = %{version}-%{release} @@ -106,6 +114,7 @@ Provides: dnf-plugin-repodiff = %{version}-%{release} Provides: dnf-plugin-repograph = %{version}-%{release} Provides: dnf-plugin-repomanage = %{version}-%{release} Provides: dnf-plugin-reposync = %{version}-%{release} +Provides: dnf-plugin-system-upgrade = %{version}-%{release} %if %{with yumcompatibility} Provides: yum-plugin-copr = %{version}-%{release} Provides: yum-plugin-changelog = %{version}-%{release} @@ -115,7 +124,7 @@ Conflicts: dnf-plugins-extras-common-data < %{dnf_plugins_extra} %description Core Plugins for DNF. This package enhances DNF with builddep, config-manager, -copr, debug, debuginfo-install, download, groups-manager, needs-restarting, repoclosure, +copr, debug, debuginfo-install, download, needs-restarting, groups-manager, repoclosure, repograph, repomanage, reposync, changelog and repodiff commands. Additionally provides generate_completion_cache passive plugin. @@ -158,8 +167,9 @@ Conflicts: python-%{name} < %{version}-%{release} %description -n python2-%{name} Core Plugins for DNF, Python 2 interface. This package enhances DNF with builddep, -config-manager, copr, degug, debuginfo-install, download, groups-manager, needs-restarting, -repoclosure, repograph, repomanage, reposync, changelog and repodiff commands. +config-manager, copr, degug, debuginfo-install, download, needs-restarting, +groups-manager, repoclosure, repograph, repomanage, reposync, changelog, +repodiff, system-upgrade, offline-upgrade and offline-distrosync commands. Additionally provides generate_completion_cache passive plugin. %endif @@ -170,6 +180,10 @@ Summary: Core Plugins for DNF BuildRequires: python3-dbus BuildRequires: python3-devel BuildRequires: python3-dnf >= %{dnf_lowest_compatible} +BuildRequires: python3-systemd +BuildRequires: pkgconfig(systemd) +BuildRequires: systemd +%{?systemd_ordering} %if 0%{?fedora} Requires: python3-distro %endif @@ -177,14 +191,17 @@ Requires: python3-dbus Requires: python3-dnf >= %{dnf_lowest_compatible} Requires: python3-hawkey >= %{hawkey_version} Requires: python3-dateutil +Requires: python3-systemd Provides: python3-dnf-plugins-extras-debug = %{version}-%{release} Provides: python3-dnf-plugins-extras-repoclosure = %{version}-%{release} Provides: python3-dnf-plugins-extras-repograph = %{version}-%{release} Provides: python3-dnf-plugins-extras-repomanage = %{version}-%{release} +Provides: python3-dnf-plugin-system-upgrade = %{version}-%{release} Obsoletes: python3-dnf-plugins-extras-debug < %{dnf_plugins_extra} Obsoletes: python3-dnf-plugins-extras-repoclosure < %{dnf_plugins_extra} Obsoletes: python3-dnf-plugins-extras-repograph < %{dnf_plugins_extra} Obsoletes: python3-dnf-plugins-extras-repomanage < %{dnf_plugins_extra} +Obsoletes: python3-dnf-plugin-system-upgrade < %{version}-%{release} Conflicts: %{name} <= 0.1.5 # let the both python plugin versions be updated simultaneously @@ -193,8 +210,9 @@ Conflicts: python-%{name} < %{version}-%{release} %description -n python3-%{name} Core Plugins for DNF, Python 3 interface. This package enhances DNF with builddep, -config-manager, copr, debug, debuginfo-install, download, groups-manager, needs-restarting, -repoclosure, repograph, repomanage, reposync, changelog and repodiff commands. +config-manager, copr, debug, debuginfo-install, download, needs-restarting, +groups-manager, repoclosure, repograph, repomanage, reposync, changelog, +repodiff, system-upgrade, offline-upgrade and offline-distrosync commands. Additionally provides generate_completion_cache passive plugin. %endif @@ -475,6 +493,17 @@ pushd build-py3 %make_install popd %endif + +%if %{with python3} +mkdir -p %{buildroot}%{_unitdir}/system-update.target.wants/ +pushd %{buildroot}%{_unitdir}/system-update.target.wants/ + ln -sr ../dnf-system-upgrade.service +popd + +ln -sf %{_mandir}/man8/dnf-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf-offline-upgrade.8.gz +ln -sf %{_mandir}/man8/dnf-system-upgrade.8.gz %{buildroot}%{_mandir}/man8/dnf-offline-distrosync.8.gz +%endif + %find_lang %{name} %if %{with yumutils} %if %{with python3} @@ -539,6 +568,9 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ %{_mandir}/man8/dnf-repograph.* %{_mandir}/man8/dnf-repomanage.* %{_mandir}/man8/dnf-reposync.* +%{_mandir}/man8/dnf-system-upgrade.* +%{_mandir}/man8/dnf-offline-upgrade.* +%{_mandir}/man8/dnf-offline-distrosync.* %if %{with yumcompatibility} %{_mandir}/man1/yum-changelog.* %{_mandir}/man8/yum-copr.* @@ -596,6 +628,7 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ %{python3_sitelib}/dnf-plugins/repograph.py %{python3_sitelib}/dnf-plugins/repomanage.py %{python3_sitelib}/dnf-plugins/reposync.py +%{python3_sitelib}/dnf-plugins/system_upgrade.py %{python3_sitelib}/dnf-plugins/__pycache__/builddep.* %{python3_sitelib}/dnf-plugins/__pycache__/changelog.* %{python3_sitelib}/dnf-plugins/__pycache__/config_manager.* @@ -611,7 +644,11 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ %{python3_sitelib}/dnf-plugins/__pycache__/repograph.* %{python3_sitelib}/dnf-plugins/__pycache__/repomanage.* %{python3_sitelib}/dnf-plugins/__pycache__/reposync.* +%{python3_sitelib}/dnf-plugins/__pycache__/system_upgrade.* %{python3_sitelib}/dnfpluginscore/ +%{_unitdir}/dnf-system-upgrade.service +%{_unitdir}/dnf-system-upgrade-cleanup.service +%{_unitdir}/system-update.target.wants/dnf-system-upgrade.service %endif %if %{with yumutils} @@ -807,9 +844,22 @@ ln -sf %{_mandir}/man1/%{yum_utils_subpackage_name}.1.gz %{buildroot}%{_mandir}/ %endif %changelog -* Wed Sep 14 2022 Marek Blaha - 4.0.21-14.1 +* Wed Mar 08 2023 Marek Blaha - 4.0.21-19 - Update translations +* Thu Jan 05 2023 Nicola Sella - 4.0.21-18 +- Show downstream warning during system-upgrade + +* Wed Nov 30 2022 Nicola Sella - 4.0.21-17 +- offline-upgrade: add support for security filters (RhBug:1939975,2139324) +- Move system-upgrade plugin to core (RhBug:2054235) + +* Wed Oct 26 2022 Nicola Sella - 4.0.21-16 +- Move system-upgrade plugin to core (RhBug:2054235) + +* Tue Sep 13 2022 Lukas Hrazky - 4.0.21-15 +- builddep: Warning when using macros with source rpms (RhBug:2077820) + * Tue Jul 19 2022 Lukas Hrazky - 4.0.21-14 - [copr] Guess EPEL chroots for CentOS Stream