SET(LIBZYPP_MAJOR "17")
SET(LIBZYPP_COMPATMINOR "22")
SET(LIBZYPP_MINOR "30")
-SET(LIBZYPP_PATCH "0")
+SET(LIBZYPP_PATCH "1")
#
-# LAST RELEASED: 17.30.0 (22)
+# LAST RELEASED: 17.30.1 (22)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
<DD>Added COMMITBEGIN/COMMITEND.</DD>
</DL></DD>
+ <DT>plugin:repoverification</DT>
+ <DD><DL>
+ <DT>\ref plugin-repoverification </DT>
+ <DT>version 0</DT>
+ <DD>Repository metadata verification beyond GPG.</DD>
+ </DL></DD>
+
<DT>plugin:services</DT>
<DD><DL>
<DT>\ref plugin-services </DT>
\subpage plugin-system Receive notification if system content has changed
+\subpage plugin-repoverification Repository metadata verification beyond GPG
+
\ref plugin-services
\ref plugin-url-resolver
Provides: libzypp(plugin:services) = 1
Provides: libzypp(plugin:system) = 1
Provides: libzypp(plugin:urlresolver) = 0
+Provides: libzypp(plugin:repoverification) = 0
Provides: libzypp(repovarexpand) = 1.1
%if 0%{?suse_version}
-------------------------------------------------------------------
+Mon May 30 14:37:57 CEST 2022 - ma@suse.de
+
+- PluginRepoverification: initial version hooked into
+ repo::Downloader and repo refresh.
+- Immediately start monitoring the download.transfer_timeout.
+ Do not wait until the first data arrived. (bsc#1199042)
+- singletrans: no dry-run commit if doing just download-only.
+- Work around cases where sat repo.start points to an invalid
+ solvable. May happen if (wrong arch) solvables were removed
+ at the beginning of the repo.
+- fix misplaced #endif SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
+ (fixes #388)
+- version 17.30.1 (22)
+
+-------------------------------------------------------------------
Fri Mar 25 17:08:46 CET 2022 - ma@suse.de
- ZConfig: Update solver settings if target changes (bsc#1196368)
"Project-Id-Version: zypp\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2021-07-26 20:11+0000\n"
+"PO-Revision-Date: 2022-04-06 23:12+0000\n"
"Last-Translator: Aleš Kastner <alkas@volny.cz>\n"
-"Language-Team: Czech <https://l10n.opensuse.org/projects/libzypp/master/cs/"
-">\n"
+"Language-Team: Czech <https://l10n.opensuse.org/projects/libzypp/master/cs/>"
+"\n"
"Language: cs\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.7.1\n"
+"X-Generator: Weblate 4.9.1\n"
#: zypp/CountryCode.cc:50
msgid "Unknown country: "
#: zypp/solver/detail/SATResolver.cc:1253
#, boost-format
msgid "%1% is not yet fully integrated into %2%."
-msgstr ""
+msgstr "%1% ještě není plně zaintegrován do %2%."
#: zypp/solver/detail/SATResolver.cc:1254
msgid ""
"Typically you want to keep the PTF and choose to not install the maintenance "
"patches."
msgstr ""
+"Obvykle budete chtít ponechat PTF a vybrat, že nechcete instalovat údržbové "
+"záplaty."
#. translator: %1% is the name of a PTF.
#: zypp/solver/detail/SATResolver.cc:1259
#, boost-format
msgid "The installed %1% blocks the desired action."
-msgstr ""
+msgstr "Nainstalovaný %1% blokuje vyžadovanou akci."
#: zypp/solver/detail/SATResolver.cc:1260
msgid "Typically you want to keep the PTF and choose to cancel the action."
-msgstr ""
+msgstr "Obvykle budete chtít ponechat PTF a vybrat zrušení této akce."
#: zypp/solver/detail/SATResolver.cc:1316
#, boost-format
#: zypp/solver/detail/SATResolver.cc:1422
#, boost-format
msgid "do not ask to delete all solvables providing %1%"
-msgstr "nepožadujte smazání všech řešitelných problémů poskytujících %1%"
+msgstr "nepožadovat smazání všech řešitelných problémů poskytujících% 1%"
#: zypp/solver/detail/SATResolver.cc:1435
#, boost-format
#: zypp/target/rpm/RpmDb.cc:1271
msgid "Package header is not signed!"
-msgstr ""
+msgstr "Hlavička balíčku není podepsaná!"
#: zypp/target/rpm/RpmDb.cc:1273
msgid "Package payload is not signed!"
-msgstr ""
+msgstr "Obsah balíčku není podepsán!"
#. Translator: %s = name of an rpm package. A list of diffs follows
#. this message.
"Project-Id-Version: zypp.fr\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2022-03-04 11:12+0000\n"
-"Last-Translator: Sophie Leroy <sophie@stoquart.com>\n"
-"Language-Team: French <https://l10n.opensuse.org/projects/libzypp/master/fr/"
-">\n"
+"PO-Revision-Date: 2022-04-02 20:12+0000\n"
+"Last-Translator: Lucie Charrier <c.chalu@free.fr>\n"
+"Language-Team: French <https://l10n.opensuse.org/projects/libzypp/master/fr/>"
+"\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
#: zypp/target/rpm/RpmDb.cc:1271
msgid "Package header is not signed!"
-msgstr ""
+msgstr "L'en-tête du paquet n'est pas signé !"
#: zypp/target/rpm/RpmDb.cc:1273
msgid "Package payload is not signed!"
"Project-Id-Version: YaST (@memory@)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2022-03-09 05:31+0000\n"
-"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
+"PO-Revision-Date: 2022-05-20 11:13+0000\n"
+"Last-Translator: Kukuh Syafaat <syafaatkukuh@gmail.com>\n"
"Language-Team: Indonesian <https://l10n.opensuse.org/projects/libzypp/master/"
"id/>\n"
"Language: id\n"
#: zypp/target/rpm/RpmDb.cc:1271
msgid "Package header is not signed!"
-msgstr ""
+msgstr "Header paket tidak ditandatangani!"
#: zypp/target/rpm/RpmDb.cc:1273
msgid "Package payload is not signed!"
-msgstr ""
+msgstr "Payload paket tidak ditandatangani!"
#. Translator: %s = name of an rpm package. A list of diffs follows
#. this message.
"Project-Id-Version: YaST (@memory@)\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2001-07-17 16:12+0200\n"
-"Last-Translator: Зоран Димовски <zoki.dimovski@gmail.com>\n"
-"Language-Team: Macedonian <i18n@suse.de>\n"
+"PO-Revision-Date: 2022-05-26 04:13+0000\n"
+"Last-Translator: Kristijan Fremen Velkovski <me@krisfremen.com>\n"
+"Language-Team: Macedonian <https://l10n.opensuse.org/projects/libzypp/master/"
+"mk/>\n"
"Language: mk\n"
"MIME-Version: 1.0\n"
"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.9.1\n"
#: zypp/CountryCode.cc:50
msgid "Unknown country: "
-msgstr ""
+msgstr "Непозната држава: "
#. Defined CountryCode constants
#. Defined LanguageCode constants
#: zypp/CountryCode.cc:149 zypp/LanguageCode.cc:148
msgid "No Code"
-msgstr ""
+msgstr "Без код"
#: zypp/CountryCode.cc:158
msgid "Andorra"
-msgstr ""
+msgstr "Андора"
# US
# fuzzy
#. :AND:020:
#: zypp/CountryCode.cc:159
-#, fuzzy
msgid "United Arab Emirates"
-msgstr "Соединетите Американски Држави"
+msgstr "Соединети Американски Држави"
#. :ARE:784:
#: zypp/CountryCode.cc:160
msgid "Afghanistan"
-msgstr ""
+msgstr "Афганистан"
# AG
#. :AFG:004:
#: zypp/CountryCode.cc:161
msgid "Antigua and Barbuda"
-msgstr "Antigua и Barbuda"
+msgstr "Антигва и Барбуда"
#. :ATG:028:
#: zypp/CountryCode.cc:162
msgid "Anguilla"
-msgstr ""
+msgstr "Ангила"
#. :AIA:660:
#: zypp/CountryCode.cc:163
msgid "Albania"
-msgstr ""
+msgstr "Албанија"
# AM
# fuzzy
#. :ALB:008:
#: zypp/CountryCode.cc:164
msgid "Armenia"
-msgstr "Ð\90Ñ\80генÑ\82ина"
+msgstr "Ð\90Ñ\80мениÑ\98а"
# AN
# fuzzy
#. :ARM:051:
#: zypp/CountryCode.cc:165
msgid "Netherlands Antilles"
-msgstr "Холандија"
+msgstr "Холандски Антили"
#. :ANT:530:
#: zypp/CountryCode.cc:166
msgid "Angola"
-msgstr ""
+msgstr "Ангола"
#. :AGO:024:
#: zypp/CountryCode.cc:167
msgid "Antarctica"
-msgstr ""
+msgstr "Антарктика"
# AR
#. :ATA:010:
#. :ARG:032:
#: zypp/CountryCode.cc:169
msgid "American Samoa"
-msgstr "Америка, Северна"
+msgstr "Америчка Самоа"
# AT
#. :ASM:016:
#. :AUS:036:
#: zypp/CountryCode.cc:172
msgid "Aruba"
-msgstr ""
+msgstr "Аруба"
# FO
# fuzzy
#. :AZE:031:
#: zypp/CountryCode.cc:175
msgid "Bosnia and Herzegovina"
-msgstr ""
+msgstr "Босна и Херцеговина"
# BB
#. :BIH:070:
#. :BEL:056:
#: zypp/CountryCode.cc:179
msgid "Burkina Faso"
-msgstr ""
+msgstr "Буркина Фасо"
# BG
#. :BFA:854:
#. :BHR:048:
#: zypp/CountryCode.cc:182
msgid "Burundi"
-msgstr ""
+msgstr "Бурунди"
#. :BDI:108:
#: zypp/CountryCode.cc:183
msgid "Benin"
-msgstr ""
+msgstr "Бенин"
#. :BEN:204:
#: zypp/CountryCode.cc:184
msgid "Bermuda"
-msgstr ""
+msgstr "Бермуда"
#. :BMU:060:
#: zypp/CountryCode.cc:185
msgid "Brunei Darussalam"
-msgstr ""
+msgstr "Брунеј"
# BO
#. :BRN:096:
#. :BHS:044:
#: zypp/CountryCode.cc:189
msgid "Bhutan"
-msgstr ""
+msgstr "Бутан"
# FO
# fuzzy
#. :BVT:074:
#: zypp/CountryCode.cc:191
msgid "Botswana"
-msgstr ""
+msgstr "Боцвана"
# BY
# fuzzy
#. :CAN:124:
#: zypp/CountryCode.cc:195
+#, fuzzy
msgid "Cocos (Keeling) Islands"
-msgstr ""
+msgstr "Кокосови Острови"
#. :CCK:166:
#. :CAF:140:
#: zypp/CountryCode.cc:196 zypp/CountryCode.cc:198
msgid "Congo"
-msgstr ""
+msgstr "Конго"
# CF
# fuzzy
#. :CHE:756:
#: zypp/CountryCode.cc:200
msgid "Cote D'Ivoire"
-msgstr ""
+msgstr "Брег на Слоновата Коска"
# FO
# fuzzy
#. :CIV:384:
#: zypp/CountryCode.cc:201
-#, fuzzy
msgid "Cook Islands"
-msgstr "Ð\98Ñ\80Ñ\81ка"
+msgstr "Ð\9aÑ\83кови Ð\9eÑ\81Ñ\82Ñ\80ови"
# CL
#. :COK:184:
#. :CHL:152:
#: zypp/CountryCode.cc:203
msgid "Cameroon"
-msgstr ""
+msgstr "Камерун"
# CN
#. :CMR:120:
#. :COL:170:
#: zypp/CountryCode.cc:206
msgid "Costa Rica"
-msgstr ""
+msgstr "Коста Рика"
# CU
# fuzzy
#. :CUB:192:
#: zypp/CountryCode.cc:208
msgid "Cape Verde"
-msgstr ""
+msgstr "Зелен ’Рт"
#. :CPV:132:
#: zypp/CountryCode.cc:209
msgid "Christmas Island"
-msgstr ""
+msgstr "Божиќен Остров"
#. :CXR:162:
#: zypp/CountryCode.cc:210
msgid "Cyprus"
-msgstr ""
+msgstr "Кипар"
# CZ
# fuzzy
#. :DEU:276:
#: zypp/CountryCode.cc:213
msgid "Djibouti"
-msgstr ""
+msgstr "Џибути"
# DK
#. :DJI:262:
#. :EGY:818:
#: zypp/CountryCode.cc:221
msgid "Western Sahara"
-msgstr ""
+msgstr "Западна Сахара"
#. :ESH:732:
#: zypp/CountryCode.cc:222
msgid "Eritrea"
-msgstr ""
+msgstr "Еритреја"
# ES
#. :ERI:232:
#. :FIN:246:
#: zypp/CountryCode.cc:226
msgid "Fiji"
-msgstr ""
+msgstr "Фиџи"
#. :FJI:242:
#: zypp/CountryCode.cc:227
msgid "Falkland Islands (Malvinas)"
-msgstr ""
+msgstr "Фолкландските Острови (Малвини)"
#. :FLK:238:
#: zypp/CountryCode.cc:228
msgid "Federated States of Micronesia"
-msgstr ""
+msgstr "Сојузни Држави на Микронезија"
# FO
# fuzzy
#. :FRA:250:
#: zypp/CountryCode.cc:231
msgid "Metropolitan France"
-msgstr ""
+msgstr "Метрополитна Франција"
#. :FXX:249:
#: zypp/CountryCode.cc:232
msgid "Gabon"
-msgstr ""
+msgstr "Габон"
#. :GAB:266:
#: zypp/CountryCode.cc:233
msgid "United Kingdom"
-msgstr ""
+msgstr "Обединето Кралство"
# GD
#. :GBR:826:
#. :GHA:288:
#: zypp/CountryCode.cc:239
msgid "Gibraltar"
-msgstr ""
+msgstr "Гибралтар"
# GL
# fuzzy
#. :GMB:270:
#: zypp/CountryCode.cc:242
msgid "Guinea"
-msgstr ""
+msgstr "Гвинеја"
#. :GIN:324:
#: zypp/CountryCode.cc:243
msgid "Guadeloupe"
-msgstr ""
+msgstr "Гваделуп"
#. :GLP:312:
#: zypp/CountryCode.cc:244
msgid "Equatorial Guinea"
-msgstr ""
+msgstr "Екваторска Гвинеја"
# GR
#. :GNQ:226:
#. :GRC:300:
#: zypp/CountryCode.cc:246
msgid "South Georgia and the South Sandwich Islands"
-msgstr ""
+msgstr "Јужна Џорџија и Јужни Сендвички Острови"
# GT
#. :SGS:239:
#. :GUM:316:
#: zypp/CountryCode.cc:249
msgid "Guinea-Bissau"
-msgstr ""
+msgstr "Гвинеја-Бисао"
#. :GNB:624:
#: zypp/CountryCode.cc:250
msgid "Guyana"
-msgstr ""
+msgstr "Гвајана"
#. :GUY:328:
#: zypp/CountryCode.cc:251
msgid "Hong Kong"
-msgstr ""
+msgstr "Хонгконг"
#. :HKG:344:
#: zypp/CountryCode.cc:252
#. :HRV:191:
#: zypp/CountryCode.cc:255
msgid "Haiti"
-msgstr ""
+msgstr "Хаити"
# HU
#. :HTI:332:
#. :ISR:376:
#: zypp/CountryCode.cc:260
msgid "Isle of Man"
-msgstr ""
+msgstr "Островот Ман"
# IN
# fuzzy
#. :IND:356:
#: zypp/CountryCode.cc:262
msgid "British Indian Ocean Territory"
-msgstr ""
+msgstr "Британска Индоокеанска Територија"
# IQ
# fuzzy
#. :IRQ:368:
#: zypp/CountryCode.cc:264
msgid "Iran"
-msgstr ""
+msgstr "Иран"
# IS
#. :IRN:364:
#. :ITA:380:
#: zypp/CountryCode.cc:267
msgid "Jersey"
-msgstr ""
+msgstr "Џерси"
# JM
# fuzzy
#. :JPN:392:
#: zypp/CountryCode.cc:271
msgid "Kenya"
-msgstr ""
+msgstr "Кенија"
# KZ
# fuzzy
#. :KHM:116:
#: zypp/CountryCode.cc:274
msgid "Kiribati"
-msgstr ""
+msgstr "Кирибати"
#. :KIR:296:
#: zypp/CountryCode.cc:275
#. :VGB:092:
#: zypp/CountryCode.cc:394
msgid "Virgin Islands, U.S."
-msgstr "ФинÑ\81ка"
+msgstr "Ð\90меÑ\80иканÑ\81ки Ð\94евÑ\81Ñ\82вени Ð\9eÑ\81Ñ\82Ñ\80ови"
#. :VIR:850:
#: zypp/CountryCode.cc:395
#. TranslatorExplanation '%s' is a pathname
#: zypp/RepoManager.cc:321 zypp/RepoManager.cc:784 zypp/RepoManager.cc:1565
#: zypp/repo/PluginServices.cc:49
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Failed to read directory '%s'"
-msgstr "Failed to parse: %s."
+msgstr "Неможеше да се прочита директориумот '%s'"
#: zypp/RepoManager.cc:331
#, boost-format
msgstr[1] ""
#: zypp/RepoManager.cc:1172 zypp/RepoManager.cc:1285 zypp/RepoManager.cc:1341
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Can't create %s"
-msgstr "Couldn't open file: %s."
+msgstr "Неможеше да се створи %s"
#: zypp/RepoManager.cc:1180
msgid "Can't create metadata cache directory."
msgstr ""
#: zypp/RepoManager.cc:1408
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Failed to cache repo (%d)."
-msgstr "Failed to parse: %s."
+msgstr "Неможеше да се кешира складиштето (%d)."
#: zypp/RepoManager.cc:1419
msgid "Unhandled repository type"
#. TranslatorExplanation '%s' is a filename
#: zypp/RepoManager.cc:1809 zypp/RepoManager.cc:2011
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Can't delete '%s'"
-msgstr "Couldn't open file: %s."
+msgstr "Неможеше да се избрише '%s'"
#: zypp/RepoManager.cc:1999 zypp/RepoManager.cc:2449
msgid "Can't figure out where the service is stored."
msgstr ""
#: zypp/target/TargetImpl.cc:441
-#, fuzzy
msgid " execution failed"
-msgstr "DBI Execution failed: %s"
+msgstr " егзекуцијата не успеа"
#. translators: We may find the same script content in files with different names.
#. Only the first occurence is executed, subsequent ones are skipped. It's a one-line
msgstr ""
#: zypp-core/zyppng/io/forkspawnengine.cc:282
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Can't chdir to '%s' (%s)."
-msgstr "Couldn't open file: %s."
+msgstr "Неможеше да се chdir-а во '%s' (%s)."
#: zypp-core/zyppng/io/forkspawnengine.cc:283
#, c-format, boost-format
msgstr ""
#: zypp-media/mediaexception.cc:33
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Failed to mount %s on %s"
-msgstr "Failed to parse: %s."
+msgstr "Неможеше да се монтира %s во %s"
#: zypp-media/mediaexception.cc:43
-#, fuzzy, c-format, boost-format
+#, boost-format, c-format
msgid "Failed to unmount %s"
-msgstr "Failed to parse: %s."
+msgstr "Неможеше да се демонтира %s"
#: zypp-media/mediaexception.cc:48
#, c-format, boost-format
"Project-Id-Version: zypp\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2020-09-15 11:48+0000\n"
-"Last-Translator: Alexander Johansen <alej0hio2007@gmail.com>\n"
+"PO-Revision-Date: 2022-05-29 21:13+0000\n"
+"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
"Language-Team: Norwegian Bokmål <https://l10n.opensuse.org/projects/libzypp/"
"master/nb/>\n"
"Language: nb\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.6.1\n"
+"X-Generator: Weblate 4.9.1\n"
#: zypp/CountryCode.cc:50
msgid "Unknown country: "
#. :BWA:072:
#: zypp/CountryCode.cc:192
msgid "Belarus"
-msgstr "Hviterussland"
+msgstr "Belarus"
# BZ
# fuzzy
#. language code: bel be
#: zypp/LanguageCode.cc:259
msgid "Belarusian"
-msgstr "Hviterussisk"
+msgstr "Belarusisk"
#. language code: bem
#: zypp/LanguageCode.cc:261
"Project-Id-Version: @PACKAGE@\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2018-03-09 22:04+0000\n"
+"PO-Revision-Date: 2022-05-29 21:13+0000\n"
"Last-Translator: Karl Ove Hufthammer <karl@huftis.org>\n"
"Language-Team: Norwegian Nynorsk <https://l10n.opensuse.org/projects/libzypp/"
"master/nn/>\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 2.18\n"
+"X-Generator: Weblate 4.9.1\n"
#: zypp/CountryCode.cc:50
msgid "Unknown country: "
#. :BWA:072:
#: zypp/CountryCode.cc:192
msgid "Belarus"
-msgstr "Kviterussland"
+msgstr "Belarus"
#. :BLR:112:
#: zypp/CountryCode.cc:193
#. language code: bel be
#: zypp/LanguageCode.cc:259
msgid "Belarusian"
-msgstr "Kviterussisk"
+msgstr "Belarusisk"
#. language code: bem
#: zypp/LanguageCode.cc:261
"Project-Id-Version: zypp\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-03-14 15:21+0100\n"
-"PO-Revision-Date: 2022-02-27 17:12+0000\n"
-"Last-Translator: Rodrigo Macedo <rmsolucoeseminformatic4@gmail.com>\n"
+"PO-Revision-Date: 2022-04-02 00:12+0000\n"
+"Last-Translator: Luiz Fernando Ranghetti <elchevive68@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://l10n.opensuse.org/projects/"
"libzypp/master/pt_BR/>\n"
"Language: pt_BR\n"
#: zypp/target/rpm/RpmDb.cc:1271
msgid "Package header is not signed!"
-msgstr ""
+msgstr "O cabeçalho do pacote não está assinado!"
#: zypp/target/rpm/RpmDb.cc:1273
msgid "Package payload is not signed!"
-msgstr ""
+msgstr "A carga útil do pacote não está assinada!"
#. Translator: %s = name of an rpm package. A list of diffs follows
#. this message.
/** \overload std::exception_ptr */
void remember( std::exception_ptr old_r );
+ /** Remembering a plain string is most probably not wanted - we \ref addHistory.
+ * It would discards the old history and replace it with this string.
+ * If that's actually your intent, explicitly wrap it into an \ref Exception.
+ */
+ void remember( const std::string & msg_r )
+ { addHistory( msg_r ); }
+ /** \overload moving */
+ void remember( std::string && msg_r )
+ { addHistory( std::move(msg_r) ); }
+
/** Add some message text to the history. */
void addHistory( const std::string & msg_r );
/** \overload moving */
WatchFile( const Pathname & path_r = Pathname(),
Initial mode = INIT )
: _path( path_r )
- {
- PathInfo pi( mode == INIT ? path_r : Pathname() );
- _size = pi.size();
- _mtime = pi.mtime();
- }
+ { ctorInit( mode ); }
+
+ WatchFile( Pathname && path_r, Initial mode = INIT )
+ : _path( std::move(path_r) )
+ { ctorInit( mode ); }
const Pathname & path() const
{ return _path; }
}
private:
+ void ctorInit( Initial mode )
+ {
+ PathInfo pi( mode == INIT ? _path : Pathname() );
+ _size = pi.size();
+ _mtime = pi.mtime();
+ }
+
+ private:
Pathname _path;
off_t _size;
time_t _mtime;
repo/Downloader.cc
repo/RepoVariables.cc
repo/RepoInfoBase.cc
+ repo/PluginRepoverification.cc
repo/PluginServices.cc
repo/ServiceRepos.cc
)
repo/Downloader.h
repo/RepoVariables.h
repo/RepoInfoBase.h
+ repo/PluginRepoverification.h
repo/PluginServices.h
repo/ServiceRepos.h
)
}
catch ( const FileCheckException &e )
{
- ZYPP_RETHROW(e);
+ throw; // let known exceptions bypass silently
}
catch ( const Exception &e )
{
- ZYPP_RETHROW(e);
+ throw; // slet known exceptions bypass silently
}
catch (...)
{
#include <zypp/repo/yum/Downloader.h>
#include <zypp/repo/susetags/Downloader.h>
#include <zypp/repo/PluginServices.h>
+#include <zypp/repo/PluginRepoverification.h>
#include <zypp/Target.h> // for Target::targetDistribution() for repo index services
#include <zypp/ZYppFactory.h> // to get the Target from ZYpp instance
/// \brief RepoManager implementation.
///
///////////////////////////////////////////////////////////////////
- struct RepoManager::Impl
+ struct ZYPP_LOCAL RepoManager::Impl
{
public:
Impl( const RepoManagerOptions &opt )
: _options(opt)
+ , _pluginRepoverification( _options.pluginsPath/"repoverification", _options.rootDir )
{
init_knownServices();
init_knownRepositories();
DefaultIntegral<bool,false> _reposDirty;
+ PluginRepoverification _pluginRepoverification;
+
private:
friend Impl * rwcowClone<Impl>( const Impl * rhs );
/** clone for RWCOW_pointer */
MIL << "Creating downloader for [ " << info.alias() << " ]" << endl;
- if ( repokind.toEnum() == RepoType::RPMMD_e )
- downloader_ptr.reset(new yum::Downloader(info, mediarootpath));
+ if ( repokind.toEnum() == RepoType::RPMMD_e ) {
+ downloader_ptr.reset(new yum::Downloader(info, mediarootpath ));
+ if ( _pluginRepoverification.checkIfNeeded() )
+ downloader_ptr->setPluginRepoverification( _pluginRepoverification ); // susetags is dead so we apply just to yum
+ }
else
downloader_ptr.reset( new susetags::Downloader(info, mediarootpath) );
, JobReport::UserData( "cmdout" ) );
}
return ret;
-#endif // SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
})();
+#endif // SINGLE_RPMTRANS_AS_DEFAULT_FOR_ZYPPER
return singleTrans;
}
_timeRcv = now;
_dnlNow = dlnow;
}
- else if ( !_dnlNow && !_dnlTotal )
- {
- // Start time counting as soon as first data arrives.
- // Skip the connection / redirection time at begin.
- return;
- }
// init or reset if time jumps back
if ( !_timeStart || _timeStart > now )
void Downloader::defaultDownloadMasterIndex( MediaSetAccess & media_r, const Pathname & destdir_r, const Pathname & masterIndex_r )
{
+ // always download them, even if repoGpgCheck is disabled
Pathname sigpath = masterIndex_r.extend( ".asc" );
Pathname keypath = masterIndex_r.extend( ".key" );
- // always download them, even if repoGpgCheck is disabled
-
//enable precache for next start() call
setMediaSetAccess( media_r );
enqueue( OnMediaLocation( sigpath, 1 ).setOptional( true ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ) );
start( destdir_r );
reset();
- FileChecker checker; // set to sigchecker if appropriate, else Null.
- ExtraSignatureFileChecker sigchecker;
- bool isSigned = PathInfo(destdir_r / sigpath).isExist();
+ // The local files are in destdir_r, if they were present on the server
+ Pathname sigpathLocal { destdir_r/sigpath };
+ Pathname keypathLocal { destdir_r/keypath };
+
+ CompositeFileChecker checkers;
+
+ if ( _pluginRepoverification && _pluginRepoverification->isNeeded() )
+ checkers.add( _pluginRepoverification->getChecker( sigpathLocal, keypathLocal, repoInfo() ) );
+
+ ExtraSignatureFileChecker sigchecker;
+ bool isSigned = PathInfo(sigpathLocal).isExist();
if ( repoInfo().repoGpgCheck() )
{
if ( isSigned || repoInfo().repoGpgCheckIsMandatory() )
{
// only add the signature if it exists
if ( isSigned )
- sigchecker.signature( destdir_r / sigpath );
+ sigchecker.signature( sigpathLocal );
// only add the key if it exists
- if ( PathInfo(destdir_r / keypath).isExist() )
- sigchecker.addPublicKey( destdir_r / keypath );
+ if ( PathInfo(keypathLocal).isExist() )
+ sigchecker.addPublicKey( keypathLocal );
// set the checker context even if the key is not known
// (unsigned repo, key file missing; bnc #495977)
{ INT << "Oops!" << endl; }
});
}
- checker = FileChecker( ref(sigchecker) ); // ref() to the local sigchecker is important as we want back fileValidated!
+ checkers.add( ref(sigchecker) ); // ref() to the local sigchecker is important as we want back fileValidated!
}
else
{
WAR << "Signature checking disabled in config of repository " << repoInfo().alias() << endl;
}
- enqueue( OnMediaLocation( masterIndex_r, 1 ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ), checker ? checker : FileChecker(NullFileChecker()) );
+ enqueue( OnMediaLocation( masterIndex_r, 1 ).setDownloadSize( ByteCount( 20, ByteCount::MB ) ), checkers );
start( destdir_r, media_r );
reset();
#ifndef ZYPP_REPO_DOWNLOADER
#define ZYPP_REPO_DOWNLOADER
+#include <optional>
+
#include <zypp/Url.h>
#include <zypp/Pathname.h>
#include <zypp-core/ui/ProgressData>
#include <zypp/MediaSetAccess.h>
#include <zypp/Fetcher.h>
#include <zypp/RepoInfo.h>
+#include <zypp/repo/PluginRepoverification.h>
namespace zypp
{
namespace repo
{
+ using zypp_private::repo::PluginRepoverification;
+
/**
* \short Downloader base class
*
const RepoInfo & repoInfo() const { return _repoinfo; }
+
+ void setPluginRepoverification( std::optional<PluginRepoverification> pluginRepoverification_r )
+ { _pluginRepoverification = std::move(pluginRepoverification_r); }
+
+ void setNoPluginRepoverification()
+ { setPluginRepoverification( std::nullopt ); }
+
protected:
/** Common workflow downloading a (signed) master index file */
void defaultDownloadMasterIndex( MediaSetAccess & media_r, const Pathname & destdir_r, const Pathname & masterIndex_r );
private:
RepoInfo _repoinfo;
+ std::optional<PluginRepoverification> _pluginRepoverification; ///< \see \ref plugin-repoverification
};
} // ns repo
} // ns zypp
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/repo/PluginRepoverification.cc
+ */
+#include <iostream>
+#include <sstream>
+
+#include "PluginRepoverification.h"
+
+#include <zypp/Globals.h>
+#include <zypp/PathInfo.h>
+#include <zypp/ExternalProgram.h>
+#include <zypp/base/LogTools.h>
+#include <zypp/base/WatchFile.h>
+
+using std::endl;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp_private
+{
+ using namespace zypp;
+ ///////////////////////////////////////////////////////////////////
+ namespace repo
+ {
+ ///////////////////////////////////////////////////////////////////
+ /// \class PluginRepoverification::Checker::Impl
+ /// \brief PluginRepoverification::Checker data storage.
+ ///////////////////////////////////////////////////////////////////
+ class PluginRepoverification::Checker::Impl
+ {
+ public:
+ Impl( RW_pointer<PluginRepoverification::Impl> parent_r,
+ Pathname sigpathLocal_r, Pathname keypathLocal_r, const RepoInfo & repo_r )
+ : _parent { parent_r }
+ , _sigpathLocal { std::move(sigpathLocal_r) }
+ , _keypathLocal { std::move(keypathLocal_r) }
+ , _repoinfo { repo_r }
+ {}
+
+ RW_pointer<PluginRepoverification::Impl> _parent;
+ Pathname _sigpathLocal;
+ Pathname _keypathLocal;
+ RepoInfo _repoinfo;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class PluginRepoverification::Impl
+ /// \brief PluginRepoverification implementation.
+ ///////////////////////////////////////////////////////////////////
+ class PluginRepoverification::Impl
+ {
+ friend std::ostream & operator<<( std::ostream & str, const Impl & obj );
+ friend std::ostream & dumpOn( std::ostream & str, const Impl & obj );
+
+ public:
+ Impl()
+ {}
+
+ Impl( Pathname plugindir_r, Pathname chroot_r )
+ : _watchPlugindir { std::move(plugindir_r), WatchFile::NO_INIT }
+ , _chroot { std::move(chroot_r) }
+ {}
+
+ ~Impl()
+ {}
+
+ bool isNeeded() const
+ { return _isNeeded; }
+
+ bool checkIfNeeded()
+ {
+ if ( _watchPlugindir.hasChanged() ) {
+ _isNeeded = false;
+ // check for at least one executable plugin inside..
+ filesystem::dirForEach( plugindir(),
+ [this]( const Pathname & dir_r, const char *const name_r ) -> bool {
+ PathInfo pi ( dir_r/name_r );
+ if ( pi.isFile() && pi.userMayRX() ) {
+ this->_isNeeded = true;
+ return false;
+ }
+ return true;
+ } );
+ }
+ return _isNeeded;
+ }
+
+ void verifyWorkflow( const Pathname & file_r, RW_pointer<PluginRepoverification::Checker::Impl> datap_r ) const
+ {
+ // Execute the plugins. They will throw if something is wrong...
+ filesystem::dirForEach( plugindir(),
+ [&,this]( const Pathname & dir_r, const char *const name_r ) -> bool {
+ PathInfo pi ( dir_r/name_r );
+ if ( pi.isFile() && pi.userMayRX() )
+ this->pluginVerify( name_r, file_r, *datap_r );
+ return true;
+ } );
+ }
+
+ private:
+ void pluginVerify( std::string plugin_r, const Pathname & file_r, const PluginRepoverification::Checker::Impl & data_r ) const
+ {
+ Pathname pluginPath { plugindir()/plugin_r };
+ if ( not _chroot.emptyOrRoot() ) {
+ pluginPath = Pathname::stripprefix( _chroot, pluginPath );
+ // we need to make sure the files are available inside the chroot
+ INT << "chroot PluginRepoverification does not yet work." << endl;
+ return;
+ }
+
+ ExternalProgram::Arguments args;
+ args.push_back( pluginPath.asString() );
+ /// NOTE: Update plugin-repoverification page if new args are supplied
+ args.push_back( "--file" );
+ args.push_back( file_r.asString() );
+ args.push_back( "--fsig" );
+ args.push_back( data_r._sigpathLocal.asString() );
+ args.push_back( "--fkey" );
+ args.push_back( data_r._keypathLocal.asString() );
+ args.push_back( "--ralias" );
+ args.push_back( data_r._repoinfo.alias() );
+ ExternalProgram cmd { args, ExternalProgram::Stderr_To_Stdout, false, -1, false, _chroot };
+
+ std::ostringstream buffer;
+ cmd >> buffer;
+
+ int ret = cmd.close();
+ if ( ret ) {
+ const std::string & msg { str::Format( "Metadata rejected by '%1%' plugin (returned %2%)" ) % plugin_r % ret };
+// ERR << buffer.str() << endl;
+// ERR << msg << endl;
+
+ ExceptionType excp { msg };
+ excp.addHistory( buffer.str() );
+ excp.addHistory( str::Format( "%1%%2% returned %3%" ) % (_chroot.emptyOrRoot()?"":"("+_chroot.asString()+")") % pluginPath % ret );
+
+ ZYPP_THROW( std::move(excp) );
+ }
+ }
+
+ const Pathname & plugindir() const
+ { return _watchPlugindir.path(); }
+
+ private:
+ WatchFile _watchPlugindir;
+ Pathname _chroot;
+ bool _isNeeded = false;
+ };
+
+ /** \relates PluginRepoverification::Impl Stream output */
+ inline std::ostream & operator<<( std::ostream & str, const PluginRepoverification::Impl & obj )
+ { return str << "PluginRepoverification::Impl"; }
+
+ /** \relates PluginRepoverification::Impl Verbose stream output */
+ inline std::ostream & dumpOn( std::ostream & str, const PluginRepoverification::Impl & obj )
+ { return str << obj; }
+
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PluginRepoverification
+ //
+ ///////////////////////////////////////////////////////////////////
+
+ PluginRepoverification::PluginRepoverification()
+ : _pimpl( new Impl )
+ {}
+
+ PluginRepoverification::PluginRepoverification( Pathname plugindir_r, Pathname chroot_r )
+ : _pimpl( new Impl( std::move(plugindir_r), std::move(chroot_r) ) )
+ {}
+
+ PluginRepoverification::~PluginRepoverification()
+ {}
+
+
+ bool PluginRepoverification::isNeeded() const
+ { return _pimpl->isNeeded(); }
+
+ bool PluginRepoverification::checkIfNeeded()
+ { return _pimpl->checkIfNeeded(); }
+
+ PluginRepoverification::Checker PluginRepoverification::getChecker( const Pathname & sigpathLocal_r, const Pathname & keypathLocal_r,
+ const RepoInfo & repo_r ) const
+ { return Checker( new Checker::Impl( _pimpl, sigpathLocal_r, keypathLocal_r, repo_r ) ); }
+
+
+ std::ostream & operator<<( std::ostream & str, const PluginRepoverification & obj )
+ { return str << *obj._pimpl; }
+
+ std::ostream & dumpOn( std::ostream & str, const PluginRepoverification & obj )
+ { return dumpOn( str, *obj._pimpl ); }
+
+ bool operator==( const PluginRepoverification & lhs, const PluginRepoverification & rhs )
+ { return lhs._pimpl == rhs._pimpl; }
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : PluginRepoverification::Checker
+ //
+ ///////////////////////////////////////////////////////////////////
+ PluginRepoverification::Checker::Checker( Impl* pimpl_r )
+ : _pimpl { pimpl_r }
+ {}
+
+ PluginRepoverification::Checker::~Checker()
+ {}
+
+ void PluginRepoverification::Checker::operator()( const Pathname & file_r ) const
+ { _pimpl->_parent->verifyWorkflow( file_r, _pimpl ); }
+
+
+ } // namespace repo
+ ///////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
--- /dev/null
+/*---------------------------------------------------------------------\
+| ____ _ __ __ ___ |
+| |__ / \ / / . \ . \ |
+| / / \ V /| _/ _/ |
+| / /__ | | | | | | |
+| /_____||_| |_| |_| |
+| |
+\---------------------------------------------------------------------*/
+/** \file zypp/repo/PluginRepoverification.h
+ */
+#ifndef ZYPP_REPO_PLUGINREPOVERIFICATION_H
+#define ZYPP_REPO_PLUGINREPOVERIFICATION_H
+
+#include <iosfwd>
+
+#include <zypp/Globals.h>
+#include <zypp/RepoInfo.h>
+#include <zypp/FileChecker.h>
+#include <zypp/base/PtrTypes.h>
+
+///////////////////////////////////////////////////////////////////
+namespace zypp_private
+{
+ using namespace zypp;
+ ///////////////////////////////////////////////////////////////////
+ namespace repo
+ {
+ ///////////////////////////////////////////////////////////////////
+ /// \class PluginRepoverificationCheckException
+ /// \brief Exceptiontype thrown if a plugins verification fails.
+ ///////////////////////////////////////////////////////////////////
+ class PluginRepoverificationCheckException : public FileCheckException
+ {
+ public:
+ PluginRepoverificationCheckException( const std::string &msg )
+ : FileCheckException(msg)
+ {}
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ /// \class PluginRepoverification
+ /// \brief Repository metadata verification beyond GPG.
+ ///
+ /// Implements the repoverification plugin setup and workflow. Also
+ /// serves as factory for a file \ref FileChecker that can be passed
+ /// to e.g. \ref repo::Downloader when fetching the repos master index file.
+ ///
+ /// If a root dir is defined, plugin scripts will be executed chrooted.
+ ///
+ /// \see \ref plugin-repoverification for more details.
+ ///////////////////////////////////////////////////////////////////
+ class PluginRepoverification
+ {
+ friend std::ostream & operator<<( std::ostream & str, const PluginRepoverification & obj );
+ friend std::ostream & dumpOn( std::ostream & str, const PluginRepoverification & obj );
+ friend bool operator==( const PluginRepoverification & lhs, const PluginRepoverification & rhs );
+
+ using ExceptionType = PluginRepoverificationCheckException;
+
+ public:
+ /** Default ctor, do nothing */
+ PluginRepoverification();
+
+ /** Ctor monitoring a \a plugindir_r and optional chroot for plugin execution */
+ PluginRepoverification( Pathname plugindir_r, Pathname chroot_r = Pathname() );
+
+ /** Dtor */
+ ~PluginRepoverification();
+
+ public:
+ /** Whether the last \ref checkIfNeeded found plugins to execute at all. */
+ bool isNeeded() const;
+
+ /** Checks whether there are plugins to execute at all. */
+ bool checkIfNeeded();
+
+ public:
+ ///////////////////////////////////////////////////////////////////
+ /// \class Checker
+ /// \brief \ref FileChecker checking all repoverification plugins.
+ ///////////////////////////////////////////////////////////////////
+ class Checker
+ {
+ public:
+ ~Checker();
+
+ /** Check the downloaded master index file.
+ * \throws PluginRepoverificationCheckException If a plugins verification fails.
+ */
+ void operator()( const Pathname & file_r ) const;
+
+ public:
+ class Impl; ///< Implementation class.
+ private:
+ friend class PluginRepoverification; ///< Factory for \ref Checker
+ Checker( Impl* pimpl );
+ private:
+ RW_pointer<Impl> _pimpl; ///< Pointer to implementation (ref).
+ };
+ ///////////////////////////////////////////////////////////////////
+
+ /** \ref FileChecker factory remembering the location of the master index files GPG signature and key. */
+ Checker getChecker( const Pathname & sigpathLocal_r, const Pathname & keypathLocal_r, const RepoInfo & repo_r ) const;
+
+ public:
+ class Impl; ///< Implementation class.
+ private:
+ RW_pointer<Impl> _pimpl; ///< Pointer to implementation (ref).
+ };
+
+ /** \relates PluginRepoverification Stream output */
+ std::ostream & operator<<( std::ostream & str, const PluginRepoverification & obj );
+
+ /** \relates PluginRepoverification Verbose stream output */
+ std::ostream & dumOn( std::ostream & str, const PluginRepoverification & obj );
+
+ /** \relates PluginRepoverification */
+ bool operator==( const PluginRepoverification & lhs, const PluginRepoverification & rhs );
+
+ /** \relates PluginRepoverification */
+ inline bool operator!=( const PluginRepoverification & lhs, const PluginRepoverification & rhs )
+ { return !( lhs == rhs ); }
+
+ } // namespace repo
+ ///////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_REPO_PLUGINREPOVERIFICATION_H
namespace detail
{
///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : SolvableIterator
- //
- /** */
+ /// \class SolvableIterator
+ /// \brief Iterate over valid Solvables in the pool.
+ /// If the Solvable passed to the ctor is not valid, advance
+ /// to the next valid solvable (or Solvable::noSolvable if the
+ /// end is reached,
class SolvableIterator : public boost::iterator_adaptor<
SolvableIterator // Derived
, CSolvable* // Base
{
public:
SolvableIterator()
- : SolvableIterator::iterator_adaptor_( 0 )
+ : SolvableIterator::iterator_adaptor_( nullptr )
{}
explicit SolvableIterator( const Solvable & val_r )
- : SolvableIterator::iterator_adaptor_( 0 )
- { assignVal( val_r ); }
+ : SolvableIterator::iterator_adaptor_( nullptr )
+ { initialAssignVal( val_r ); }
explicit SolvableIterator( SolvableIdType id_r )
- : SolvableIterator::iterator_adaptor_( 0 )
- { assignVal( Solvable( id_r ) ); }
+ : SolvableIterator::iterator_adaptor_( nullptr )
+ { initialAssignVal( Solvable(id_r) ); }
private:
friend class boost::iterator_core_access;
{ assignVal( _val.nextInPool() ); }
private:
+ void initialAssignVal( const Solvable & val_r )
+ { assignVal( val_r ? val_r : val_r.nextInPool() ); }
+
void assignVal( const Solvable & val_r )
{ _val = val_r; base_reference() = _val.get(); }
}
else
{
- // single trans mode does a test install via rpm
- if ( policy_r.singleTransModeEnabled() ) {
- commitInSingleTransaction( policy_r, packageCache, result );
- } else {
- if ( ! policy_r.dryRun() )
- {
+ if ( ! policy_r.dryRun() )
+ {
+ if ( policy_r.singleTransModeEnabled() ) {
+ commitInSingleTransaction( policy_r, packageCache, result );
+ } else {
// if cache is preloaded, check for file conflicts
commitFindFileConflicts( policy_r, result );
commit( policy_r, packageCache, result );
}
- else
- {
- DBG << "dryRun/downloadOnly: Not installing/deleting anything." << endl;
- if ( explicitDryRun ) {
+ }
+ else
+ {
+ DBG << "dryRun/downloadOnly: Not installing/deleting anything." << endl;
+ if ( explicitDryRun ) {
+ if ( policy_r.singleTransModeEnabled() ) {
+ // single trans mode does a test install via rpm
+ commitInSingleTransaction( policy_r, packageCache, result );
+ } else {
// if cache is preloaded, check for file conflicts
commitFindFileConflicts( policy_r, result );
}