linuxfabrik-lib 2.2.0__tar.gz → 2.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {linuxfabrik_lib-2.2.0/linuxfabrik_lib.egg-info → linuxfabrik_lib-2.3.0}/PKG-INFO +1 -1
  2. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/distro.py +3 -3
  3. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/endoflifedate.py +197 -64
  4. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0/linuxfabrik_lib.egg-info}/PKG-INFO +1 -1
  5. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/net.py +9 -5
  6. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/pyproject.toml +1 -1
  7. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/shell.py +36 -23
  8. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/txt.py +8 -8
  9. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/LICENSE.txt +0 -0
  10. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/README.md +0 -0
  11. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/__init__.py +0 -0
  12. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/args.py +0 -0
  13. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/base.py +0 -0
  14. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/cache.py +0 -0
  15. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/db_mysql.py +0 -0
  16. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/db_sqlite.py +0 -0
  17. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/disk.py +0 -0
  18. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/dmidecode.py +0 -0
  19. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/feedparser.py +0 -0
  20. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/globals.py +0 -0
  21. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/grassfish.py +0 -0
  22. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/huawei.py +0 -0
  23. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/human.py +0 -0
  24. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/icinga.py +0 -0
  25. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/infomaniak.py +0 -0
  26. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/jitsi.py +0 -0
  27. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/keycloak.py +0 -0
  28. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/lftest.py +0 -0
  29. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/librenms.py +0 -0
  30. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/linuxfabrik_lib.egg-info/SOURCES.txt +0 -0
  31. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/linuxfabrik_lib.egg-info/dependency_links.txt +0 -0
  32. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/linuxfabrik_lib.egg-info/requires.txt +0 -0
  33. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/linuxfabrik_lib.egg-info/top_level.txt +0 -0
  34. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/nodebb.py +0 -0
  35. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/powershell.py +0 -0
  36. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/psutil.py +0 -0
  37. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/qts.py +0 -0
  38. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/redfish.py +0 -0
  39. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/rocket.py +0 -0
  40. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/setup.cfg +0 -0
  41. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/smb.py +0 -0
  42. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/time.py +0 -0
  43. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/uptimerobot.py +0 -0
  44. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/url.py +0 -0
  45. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/veeam.py +0 -0
  46. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/version.py +0 -0
  47. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/wildfly.py +0 -0
  48. {linuxfabrik_lib-2.2.0 → linuxfabrik_lib-2.3.0}/winrm.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: linuxfabrik-lib
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project.
5
5
  Author-email: "Linuxfabrik GmbH, Zurich, Switzerland" <info@linuxfabrik.ch>
6
6
  Project-URL: Homepage, https://github.com/Linuxfabrik/lib
@@ -17,7 +17,7 @@ Source Code is taken, converted, shortened and modified from:
17
17
  """
18
18
 
19
19
  __author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
20
- __version__ = '2025042002'
20
+ __version__ = '2025061001'
21
21
 
22
22
 
23
23
  import os
@@ -51,7 +51,7 @@ SEARCH_STRING = {
51
51
 
52
52
  OS_FAMILY_MAP = {
53
53
  'RedHat': ['RedHat', 'RHEL', 'CentOS', 'Scientific', 'OracleLinux', 'Fedora', 'AlmaLinux', 'Rocky'],
54
- 'Debian': ['Debian', 'Debian GNU/Linux', 'Ubuntu', 'Raspbian', 'Pop!_OS', 'Kali', 'Parrot', 'Devuan', 'Deepin', 'Mint'],
54
+ 'Debian': ['Debian', 'Debian GNU/Linux', 'Ubuntu', 'Raspbian', 'Pop!_OS', 'Kali', 'Parrot', 'Devuan', 'Devuan GNU/Linux', 'Deepin', 'Mint'],
55
55
  'Suse': ['SUSE', 'openSUSE', 'SLES', 'SLED'],
56
56
  'Archlinux': ['Archlinux', 'Manjaro', 'Antergos'],
57
57
  'Gentoo': ['Gentoo', 'Funtoo'],
@@ -400,7 +400,7 @@ def get_distribution_facts():
400
400
  """
401
401
  facts = _process_dist_files()
402
402
 
403
- distro = facts.get('distribution', 'NA')
403
+ distro = facts.get('distribution_file_variety', 'distribution')
404
404
  facts['os_family'] = _map_os_family(distro) # returns 'RedHat', for example
405
405
 
406
406
  cmd = '. /etc/os-release && echo "$NAME $VERSION"'
@@ -462,22 +462,22 @@ ENDOFLIFE_DATE = {
462
462
  'https://endoflife.date/api/gitlab.json': [
463
463
  { 'cycle': '18.0',
464
464
  'eol': '2025-08-21',
465
- 'latest': '18.0.1',
466
- 'latestReleaseDate': '2025-05-21',
465
+ 'latest': '18.0.2',
466
+ 'latestReleaseDate': '2025-06-11',
467
467
  'lts': False,
468
468
  'releaseDate': '2025-05-15',
469
469
  'support': '2025-06-19'},
470
470
  { 'cycle': '17.11',
471
471
  'eol': '2025-07-17',
472
- 'latest': '17.11.3',
473
- 'latestReleaseDate': '2025-05-21',
472
+ 'latest': '17.11.4',
473
+ 'latestReleaseDate': '2025-06-11',
474
474
  'lts': False,
475
475
  'releaseDate': '2025-04-16',
476
476
  'support': '2025-05-15'},
477
477
  { 'cycle': '17.10',
478
478
  'eol': '2025-06-19',
479
- 'latest': '17.10.7',
480
- 'latestReleaseDate': '2025-05-21',
479
+ 'latest': '17.10.8',
480
+ 'latestReleaseDate': '2025-06-11',
481
481
  'lts': False,
482
482
  'releaseDate': '2025-03-19',
483
483
  'support': '2025-04-17'},
@@ -823,43 +823,43 @@ ENDOFLIFE_DATE = {
823
823
  'https://endoflife.date/api/grafana.json': [
824
824
  { 'cycle': '12.0',
825
825
  'eol': '2026-01-31',
826
- 'latest': '12.0.1',
827
- 'latestReleaseDate': '2025-05-22',
826
+ 'latest': '12.0.2',
827
+ 'latestReleaseDate': '2025-06-17',
828
828
  'lts': False,
829
829
  'releaseDate': '2025-05-05',
830
830
  'support': True},
831
831
  { 'cycle': '11.6',
832
832
  'eol': '2026-06-30',
833
- 'latest': '11.6.2',
834
- 'latestReleaseDate': '2025-05-22',
833
+ 'latest': '11.6.3',
834
+ 'latestReleaseDate': '2025-06-17',
835
835
  'lts': False,
836
836
  'releaseDate': '2025-03-25',
837
837
  'support': '2025-05-05'},
838
838
  { 'cycle': '11.5',
839
839
  'eol': '2025-10-31',
840
- 'latest': '11.5.5',
841
- 'latestReleaseDate': '2025-05-22',
840
+ 'latest': '11.5.6',
841
+ 'latestReleaseDate': '2025-06-17',
842
842
  'lts': False,
843
843
  'releaseDate': '2025-01-28',
844
844
  'support': '2025-03-25'},
845
845
  { 'cycle': '11.4',
846
846
  'eol': '2025-09-30',
847
- 'latest': '11.4.5',
848
- 'latestReleaseDate': '2025-05-22',
847
+ 'latest': '11.4.6',
848
+ 'latestReleaseDate': '2025-06-17',
849
849
  'lts': False,
850
850
  'releaseDate': '2024-12-05',
851
851
  'support': '2025-01-28'},
852
852
  { 'cycle': '11.3',
853
853
  'eol': '2025-07-31',
854
- 'latest': '11.3.7',
855
- 'latestReleaseDate': '2025-05-22',
854
+ 'latest': '11.3.8',
855
+ 'latestReleaseDate': '2025-06-17',
856
856
  'lts': False,
857
857
  'releaseDate': '2024-10-22',
858
858
  'support': '2024-12-05'},
859
859
  { 'cycle': '11.2',
860
860
  'eol': '2025-05-31',
861
- 'latest': '11.2.10',
862
- 'latestReleaseDate': '2025-05-22',
861
+ 'latest': '11.2.10+security-01',
862
+ 'latestReleaseDate': '2025-06-12',
863
863
  'lts': False,
864
864
  'releaseDate': '2024-08-27',
865
865
  'support': '2024-10-22'},
@@ -879,8 +879,8 @@ ENDOFLIFE_DATE = {
879
879
  'support': '2024-06-21'},
880
880
  { 'cycle': '10.4',
881
881
  'eol': '2025-06-30',
882
- 'latest': '10.4.19',
883
- 'latestReleaseDate': '2025-05-22',
882
+ 'latest': '10.4.19+security-01',
883
+ 'latestReleaseDate': '2025-06-12',
884
884
  'lts': False,
885
885
  'releaseDate': '2024-03-05',
886
886
  'support': '2025-06-30'},
@@ -981,14 +981,14 @@ ENDOFLIFE_DATE = {
981
981
  'https://endoflife.date/api/graylog.json': [
982
982
  { 'cycle': '6.2',
983
983
  'eol': False,
984
- 'latest': '6.2.2',
985
- 'latestReleaseDate': '2025-05-07',
984
+ 'latest': '6.2.3',
985
+ 'latestReleaseDate': '2025-06-04',
986
986
  'lts': False,
987
987
  'releaseDate': '2025-04-28'},
988
988
  { 'cycle': '6.1',
989
989
  'eol': False,
990
- 'latest': '6.1.11',
991
- 'latestReleaseDate': '2025-05-07',
990
+ 'latest': '6.1.12',
991
+ 'latestReleaseDate': '2025-06-04',
992
992
  'lts': False,
993
993
  'releaseDate': '2024-10-18'},
994
994
  { 'cycle': '6.0',
@@ -1139,6 +1139,123 @@ ENDOFLIFE_DATE = {
1139
1139
  ],
1140
1140
 
1141
1141
 
1142
+ 'https://endoflife.date/api/icinga.json': [
1143
+ { 'cycle': '2.14',
1144
+ 'eol': False,
1145
+ 'latest': '2.14.6',
1146
+ 'latestReleaseDate': '2025-05-21',
1147
+ 'lts': False,
1148
+ 'releaseDate': '2023-07-12',
1149
+ 'support': True},
1150
+ { 'cycle': '2.13',
1151
+ 'eol': False,
1152
+ 'latest': '2.13.12',
1153
+ 'latestReleaseDate': '2025-05-22',
1154
+ 'lts': False,
1155
+ 'releaseDate': '2021-08-02',
1156
+ 'support': '2023-07-12'},
1157
+ { 'cycle': '2.12',
1158
+ 'eol': '2023-07-12',
1159
+ 'latest': '2.12.12',
1160
+ 'latestReleaseDate': '2025-05-22',
1161
+ 'lts': False,
1162
+ 'releaseDate': '2020-08-03',
1163
+ 'support': '2021-08-02'},
1164
+ { 'cycle': '2.11',
1165
+ 'eol': '2021-08-02',
1166
+ 'latest': '2.11.12',
1167
+ 'latestReleaseDate': '2024-10-29',
1168
+ 'lts': False,
1169
+ 'releaseDate': '2019-09-19',
1170
+ 'support': '2020-08-03'},
1171
+ { 'cycle': '2.10',
1172
+ 'eol': '2020-08-03',
1173
+ 'latest': '2.12.10',
1174
+ 'latestReleaseDate': '2023-02-16',
1175
+ 'lts': False,
1176
+ 'releaseDate': '2018-10-11',
1177
+ 'support': '2019-09-19'},
1178
+ { 'cycle': '2.9',
1179
+ 'eol': '2018-10-11',
1180
+ 'latest': '2.9.3',
1181
+ 'latestReleaseDate': '2019-07-30',
1182
+ 'lts': False,
1183
+ 'releaseDate': '2018-07-17',
1184
+ 'support': '2018-10-11'},
1185
+ { 'cycle': '2.8',
1186
+ 'eol': '2018-07-17',
1187
+ 'latest': '2.8.4',
1188
+ 'latestReleaseDate': '2018-04-25',
1189
+ 'lts': False,
1190
+ 'releaseDate': '2017-11-16',
1191
+ 'support': '2018-07-17'},
1192
+ { 'cycle': '2.7',
1193
+ 'eol': '2017-11-16',
1194
+ 'latest': '2.7.2',
1195
+ 'latestReleaseDate': '2017-11-09',
1196
+ 'lts': False,
1197
+ 'releaseDate': '2017-08-02',
1198
+ 'support': '2017-11-16'},
1199
+ { 'cycle': '2.6',
1200
+ 'eol': '2017-08-02',
1201
+ 'latest': '2.6.3',
1202
+ 'latestReleaseDate': '2017-03-29',
1203
+ 'lts': False,
1204
+ 'releaseDate': '2016-12-13',
1205
+ 'support': '2017-08-02'},
1206
+ { 'cycle': '2.5',
1207
+ 'eol': '2016-12-13',
1208
+ 'latest': '2.5.4',
1209
+ 'latestReleaseDate': '2016-08-30',
1210
+ 'lts': False,
1211
+ 'releaseDate': '2016-08-22',
1212
+ 'support': '2016-12-13'},
1213
+ { 'cycle': '2.4',
1214
+ 'eol': '2016-08-22',
1215
+ 'latest': '2.4.10',
1216
+ 'latestReleaseDate': '2016-05-19',
1217
+ 'lts': False,
1218
+ 'releaseDate': '2015-11-16',
1219
+ 'support': '2016-08-22'},
1220
+ { 'cycle': '2.3',
1221
+ 'eol': '2015-11-16',
1222
+ 'latest': '2.3.11',
1223
+ 'latestReleaseDate': '2015-10-19',
1224
+ 'lts': False,
1225
+ 'releaseDate': '2015-03-09',
1226
+ 'support': '2015-11-16'},
1227
+ { 'cycle': '2.2',
1228
+ 'eol': '2015-03-09',
1229
+ 'latest': '2.2.4',
1230
+ 'latestReleaseDate': '2015-02-05',
1231
+ 'lts': False,
1232
+ 'releaseDate': '2014-11-17',
1233
+ 'support': '2015-03-09'},
1234
+ { 'cycle': '2.1',
1235
+ 'eol': '2014-11-17',
1236
+ 'latest': '2.1.1',
1237
+ 'latestReleaseDate': '2014-09-16',
1238
+ 'lts': False,
1239
+ 'releaseDate': '2014-08-29',
1240
+ 'support': '2014-11-17'},
1241
+ { 'cycle': '2.0',
1242
+ 'eol': '2014-08-29',
1243
+ 'latest': '2.0.2',
1244
+ 'latestReleaseDate': '2014-08-07',
1245
+ 'lts': False,
1246
+ 'releaseDate': '2014-06-16',
1247
+ 'support': '2014-08-29'},
1248
+ { 'cycle': '1',
1249
+ 'eol': '2018-12-31',
1250
+ 'latest': '1.14.2',
1251
+ 'latestReleaseDate': '2017-12-20',
1252
+ 'link': None,
1253
+ 'lts': False,
1254
+ 'releaseDate': '2009-12-15',
1255
+ 'support': '2014-06-16'},
1256
+ ],
1257
+
1258
+
1142
1259
  'https://endoflife.date/api/keycloak.json': [
1143
1260
  { 'cycle': '26.2',
1144
1261
  'eol': False,
@@ -1276,6 +1393,13 @@ ENDOFLIFE_DATE = {
1276
1393
 
1277
1394
 
1278
1395
  'https://endoflife.date/api/mariadb.json': [
1396
+ { 'cycle': '11.8',
1397
+ 'eol': '2028-06-04',
1398
+ 'extendedSupport': '2033-10-15',
1399
+ 'latest': '11.8.2',
1400
+ 'latestReleaseDate': '2025-06-04',
1401
+ 'lts': True,
1402
+ 'releaseDate': '2025-06-04'},
1279
1403
  { 'cycle': '11.7',
1280
1404
  'eol': '2025-05-12',
1281
1405
  'extendedSupport': False,
@@ -1626,24 +1750,24 @@ ENDOFLIFE_DATE = {
1626
1750
  'https://endoflife.date/api/moodle.json': [
1627
1751
  { 'cycle': '5.0',
1628
1752
  'eol': '2026-10-05',
1629
- 'latest': '5.0.0',
1630
- 'latestReleaseDate': '2025-04-13',
1753
+ 'latest': '5.0.1',
1754
+ 'latestReleaseDate': '2025-06-09',
1631
1755
  'lts': False,
1632
1756
  'releaseDate': '2025-04-14',
1633
1757
  'support': '2026-04-20',
1634
1758
  'supportedPhpVersions': '8.1 - 8.4'},
1635
1759
  { 'cycle': '4.5',
1636
1760
  'eol': '2027-10-06',
1637
- 'latest': '4.5.4',
1638
- 'latestReleaseDate': '2025-04-13',
1761
+ 'latest': '4.5.5',
1762
+ 'latestReleaseDate': '2025-06-09',
1639
1763
  'lts': True,
1640
1764
  'releaseDate': '2024-10-07',
1641
1765
  'support': '2025-10-06',
1642
1766
  'supportedPhpVersions': '8.1 - 8.3'},
1643
1767
  { 'cycle': '4.4',
1644
1768
  'eol': '2025-12-08',
1645
- 'latest': '4.4.8',
1646
- 'latestReleaseDate': '2025-04-13',
1769
+ 'latest': '4.4.9',
1770
+ 'latestReleaseDate': '2025-06-09',
1647
1771
  'lts': False,
1648
1772
  'releaseDate': '2024-04-22',
1649
1773
  'support': '2025-04-21',
@@ -1666,8 +1790,8 @@ ENDOFLIFE_DATE = {
1666
1790
  'supportedPhpVersions': '8.0 - 8.2'},
1667
1791
  { 'cycle': '4.1',
1668
1792
  'eol': '2025-12-08',
1669
- 'latest': '4.1.18',
1670
- 'latestReleaseDate': '2025-04-13',
1793
+ 'latest': '4.1.19',
1794
+ 'latestReleaseDate': '2025-06-09',
1671
1795
  'lts': True,
1672
1796
  'releaseDate': '2022-11-28',
1673
1797
  'support': '2023-12-11',
@@ -1790,6 +1914,7 @@ ENDOFLIFE_DATE = {
1790
1914
  'eol': '2021-02-28',
1791
1915
  'latest': '5.6.51',
1792
1916
  'latestReleaseDate': '2021-01-05',
1917
+ 'link': 'https://web.archive.org/web/20211229071247/https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-51.html',
1793
1918
  'lts': False,
1794
1919
  'releaseDate': '2013-02-01',
1795
1920
  'support': '2018-02-28'},
@@ -1797,6 +1922,7 @@ ENDOFLIFE_DATE = {
1797
1922
  'eol': '2018-12-31',
1798
1923
  'latest': '5.5.63',
1799
1924
  'latestReleaseDate': '2018-12-21',
1925
+ 'link': None,
1800
1926
  'lts': False,
1801
1927
  'releaseDate': '2010-12-03',
1802
1928
  'support': '2015-12-31'},
@@ -1806,14 +1932,14 @@ ENDOFLIFE_DATE = {
1806
1932
  'https://endoflife.date/api/nextcloud.json': [
1807
1933
  { 'cycle': '31',
1808
1934
  'eol': '2026-02-28',
1809
- 'latest': '31.0.5',
1810
- 'latestReleaseDate': '2025-05-15',
1935
+ 'latest': '31.0.6',
1936
+ 'latestReleaseDate': '2025-06-12',
1811
1937
  'lts': False,
1812
1938
  'releaseDate': '2025-02-25'},
1813
1939
  { 'cycle': '30',
1814
1940
  'eol': '2025-09-30',
1815
- 'latest': '30.0.11',
1816
- 'latestReleaseDate': '2025-05-15',
1941
+ 'latest': '30.0.12',
1942
+ 'latestReleaseDate': '2025-06-12',
1817
1943
  'lts': False,
1818
1944
  'releaseDate': '2024-09-14'},
1819
1945
  { 'cycle': '29',
@@ -1952,15 +2078,15 @@ ENDOFLIFE_DATE = {
1952
2078
  'https://endoflife.date/api/php.json': [
1953
2079
  { 'cycle': '8.4',
1954
2080
  'eol': '2028-12-31',
1955
- 'latest': '8.4.7',
1956
- 'latestReleaseDate': '2025-05-08',
2081
+ 'latest': '8.4.8',
2082
+ 'latestReleaseDate': '2025-06-05',
1957
2083
  'lts': False,
1958
2084
  'releaseDate': '2024-11-21',
1959
2085
  'support': '2026-12-31'},
1960
2086
  { 'cycle': '8.3',
1961
2087
  'eol': '2027-12-31',
1962
- 'latest': '8.3.21',
1963
- 'latestReleaseDate': '2025-05-08',
2088
+ 'latest': '8.3.22',
2089
+ 'latestReleaseDate': '2025-06-05',
1964
2090
  'lts': False,
1965
2091
  'releaseDate': '2023-11-23',
1966
2092
  'support': '2025-12-31'},
@@ -2322,36 +2448,36 @@ ENDOFLIFE_DATE = {
2322
2448
  'https://endoflife.date/api/python.json': [
2323
2449
  { 'cycle': '3.13',
2324
2450
  'eol': '2029-10-31',
2325
- 'latest': '3.13.3',
2326
- 'latestReleaseDate': '2025-04-08',
2451
+ 'latest': '3.13.5',
2452
+ 'latestReleaseDate': '2025-06-11',
2327
2453
  'lts': False,
2328
2454
  'releaseDate': '2024-10-07',
2329
2455
  'support': '2026-10-01'},
2330
2456
  { 'cycle': '3.12',
2331
2457
  'eol': '2028-10-31',
2332
- 'latest': '3.12.10',
2333
- 'latestReleaseDate': '2025-04-08',
2458
+ 'latest': '3.12.11',
2459
+ 'latestReleaseDate': '2025-06-03',
2334
2460
  'lts': False,
2335
2461
  'releaseDate': '2023-10-02',
2336
2462
  'support': '2025-04-02'},
2337
2463
  { 'cycle': '3.11',
2338
2464
  'eol': '2027-10-31',
2339
- 'latest': '3.11.12',
2340
- 'latestReleaseDate': '2025-04-08',
2465
+ 'latest': '3.11.13',
2466
+ 'latestReleaseDate': '2025-06-03',
2341
2467
  'lts': False,
2342
2468
  'releaseDate': '2022-10-24',
2343
2469
  'support': '2024-04-01'},
2344
2470
  { 'cycle': '3.10',
2345
2471
  'eol': '2026-10-31',
2346
- 'latest': '3.10.17',
2347
- 'latestReleaseDate': '2025-04-08',
2472
+ 'latest': '3.10.18',
2473
+ 'latestReleaseDate': '2025-06-03',
2348
2474
  'lts': False,
2349
2475
  'releaseDate': '2021-10-04',
2350
2476
  'support': '2023-04-05'},
2351
2477
  { 'cycle': '3.9',
2352
2478
  'eol': '2025-10-31',
2353
- 'latest': '3.9.22',
2354
- 'latestReleaseDate': '2025-04-08',
2479
+ 'latest': '3.9.23',
2480
+ 'latestReleaseDate': '2025-06-03',
2355
2481
  'lts': False,
2356
2482
  'releaseDate': '2020-10-05',
2357
2483
  'support': '2022-05-17'},
@@ -2594,45 +2720,52 @@ ENDOFLIFE_DATE = {
2594
2720
 
2595
2721
 
2596
2722
  'https://endoflife.date/api/rocketchat.json': [
2723
+ { 'cycle': '7.7',
2724
+ 'eol': '2025-11-30',
2725
+ 'latest': '7.7.1',
2726
+ 'latestReleaseDate': '2025-06-12',
2727
+ 'lts': False,
2728
+ 'releaseDate': '2025-05-31',
2729
+ 'support': '2025-05-31'},
2597
2730
  { 'cycle': '7.6',
2598
2731
  'eol': '2025-11-30',
2599
- 'latest': '7.6.1',
2600
- 'latestReleaseDate': '2025-05-23',
2732
+ 'latest': '7.6.3',
2733
+ 'latestReleaseDate': '2025-06-06',
2601
2734
  'lts': False,
2602
2735
  'releaseDate': '2025-05-13',
2603
2736
  'support': '2025-05-13'},
2604
2737
  { 'cycle': '7.5',
2605
2738
  'eol': '2025-10-31',
2606
- 'latest': '7.5.1',
2607
- 'latestReleaseDate': '2025-04-08',
2739
+ 'latest': '7.5.2',
2740
+ 'latestReleaseDate': '2025-06-06',
2608
2741
  'lts': False,
2609
2742
  'releaseDate': '2025-04-07',
2610
2743
  'support': '2025-04-07'},
2611
2744
  { 'cycle': '7.4',
2612
2745
  'eol': '2025-08-31',
2613
- 'latest': '7.4.2',
2614
- 'latestReleaseDate': '2025-04-08',
2746
+ 'latest': '7.4.3',
2747
+ 'latestReleaseDate': '2025-06-06',
2615
2748
  'lts': False,
2616
2749
  'releaseDate': '2025-03-05',
2617
2750
  'support': '2025-03-05'},
2618
2751
  { 'cycle': '7.3',
2619
2752
  'eol': '2025-07-31',
2620
- 'latest': '7.3.4',
2621
- 'latestReleaseDate': '2025-03-11',
2753
+ 'latest': '7.3.5',
2754
+ 'latestReleaseDate': '2025-06-06',
2622
2755
  'lts': False,
2623
2756
  'releaseDate': '2025-01-31',
2624
2757
  'support': '2025-01-31'},
2625
2758
  { 'cycle': '7.2',
2626
2759
  'eol': '2025-07-31',
2627
- 'latest': '7.2.5',
2628
- 'latestReleaseDate': '2025-03-01',
2760
+ 'latest': '7.2.6',
2761
+ 'latestReleaseDate': '2025-06-06',
2629
2762
  'lts': False,
2630
2763
  'releaseDate': '2025-01-07',
2631
2764
  'support': '2025-01-07'},
2632
2765
  { 'cycle': '7.1',
2633
2766
  'eol': '2025-06-30',
2634
- 'latest': '7.1.5',
2635
- 'latestReleaseDate': '2025-03-01',
2767
+ 'latest': '7.1.6',
2768
+ 'latestReleaseDate': '2025-06-06',
2636
2769
  'lts': False,
2637
2770
  'releaseDate': '2024-12-04',
2638
2771
  'support': '2024-12-04'},
@@ -3095,8 +3228,8 @@ ENDOFLIFE_DATE = {
3095
3228
  'https://endoflife.date/api/valkey.json': [
3096
3229
  { 'cycle': '8.1',
3097
3230
  'eol': False,
3098
- 'latest': '8.1.1',
3099
- 'latestReleaseDate': '2025-04-23',
3231
+ 'latest': '8.1.2',
3232
+ 'latestReleaseDate': '2025-06-11',
3100
3233
  'lts': False,
3101
3234
  'releaseDate': '2025-03-31',
3102
3235
  'support': True},
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: linuxfabrik-lib
3
- Version: 2.2.0
3
+ Version: 2.3.0
4
4
  Summary: Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project.
5
5
  Author-email: "Linuxfabrik GmbH, Zurich, Switzerland" <info@linuxfabrik.ch>
6
6
  Project-URL: Homepage, https://github.com/Linuxfabrik/lib
@@ -13,7 +13,7 @@
13
13
  """
14
14
 
15
15
  __author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
16
- __version__ = '2025052001'
16
+ __version__ = '2025053001'
17
17
 
18
18
  import random
19
19
  import re
@@ -327,10 +327,14 @@ def fetch_ssl(host, port, msg=None, timeout=3):
327
327
  >>> success, response = fetch_ssl('example.com', 443, b'GET / HTTP/1.0\\r\\nHost: example.com\\r\\n\\r\\n')
328
328
  """
329
329
  def open_ssl_socket():
330
- context = ssl.create_default_context()
331
- # forcing TLS 1.2+
332
- ctx.options |= ssl.OP_NO_TLSv1
333
- ctx.options |= ssl.OP_NO_TLSv1_1
330
+ # PROTOCOL_TLS_CLIENT automatically disables SSLv2/3 and
331
+ # TLSv1.0/1.1 on recent OpenSSL builds
332
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
333
+
334
+ # context.check_hostname = True
335
+ # context.verify_mode = ssl.CERT_REQUIRED
336
+ context.minimum_version = ssl.TLSVersion.TLSv1_2 # enforce at least TLS 1.2 just to be sure
337
+
334
338
  raw_sock = socket.socket(socket.AF_INET, SOCK_TCP)
335
339
  return context.wrap_socket(raw_sock, server_hostname=host)
336
340
 
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "linuxfabrik-lib"
9
- version = "2.2.0"
9
+ version = "2.3.0"
10
10
  description = "Python libraries used in various Linuxfabrik projects, including the 'Linuxfabrik Monitoring Plugins' project."
11
11
  readme = "README.md"
12
12
  authors = [
@@ -12,7 +12,7 @@
12
12
  """
13
13
 
14
14
  __author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
15
- __version__ = '2025042001'
15
+ __version__ = '2025060401'
16
16
 
17
17
 
18
18
  import os
@@ -84,51 +84,64 @@ def get_command_output(cmd, regex=None):
84
84
  return output
85
85
 
86
86
 
87
- def shell_exec(cmd, env=None, shell=False, stdin='', cwd=None, timeout=None):
87
+ def shell_exec(cmd, env=None, shell=False, stdin='', cwd=None, timeout=None, lc_all='C'):
88
88
  """
89
89
  Execute a command in a subprocess with flexible options for shell execution, environment
90
90
  variables, piping, standard input, working directory, and a timeout.
91
91
 
92
- On Windows, the function changes the codepage to 65001 (UTF-8) so that command output is
92
+ On Windows, the function changes the code page to 65001 (UTF-8) so that command output is
93
93
  handled in UTF-8.
94
94
 
95
95
  ### Parameters
96
96
  - **cmd** (`str`):
97
- The command string to execute. Use `|` to separate piped commands.
97
+ The command string to execute. If using pipes (`|`), individual commands will be run
98
+ in a pipeline when `shell=False`. If `shell=True`, the entire string is passed to the shell.
98
99
  - **env** (`dict`, optional):
99
100
  A dictionary of environment variables to merge with the current OS environment.
100
101
  Defaults to the current environment.
101
102
  - **shell** (`bool`, optional):
102
- If True, execute using the shell. Required when using shell features or stdin.
103
- Defaults to False.
103
+ If True, execute the command through the shell. Required when using shell features
104
+ (e.g., redirection, globbing) or when providing `stdin`. Defaults to False.
104
105
  - **stdin** (`str`, optional):
105
- A string to pass as standard input to the command. Defaults to ''.
106
+ A string to pass as standard input to the command. If non‐empty, `shell` will be set
107
+ to True on Windows. Defaults to an empty string.
106
108
  - **cwd** (`str`, optional):
107
109
  Working directory in which to execute the command. Defaults to None (current directory).
108
110
  - **timeout** (`int` or `float`, optional):
109
- Maximum time (in seconds) to allow the command to run. If exceeded, the process is terminated.
110
- Defaults to None.
111
+ Maximum time (in seconds) to allow the command to run. If exceeded, the process is
112
+ terminated. Defaults to None (no timeout).
113
+ - **lc_all** (`str`, optional):
114
+ Value to set for the `LC_ALL` environment variable, forcing command output locale.
115
+ Defaults to `'C'` (POSIX "C" locale, i.e., English).
111
116
 
112
117
  ### Returns
113
118
  - **tuple**:
114
- On success:
115
- `(True, (stdout, stderr, return_code))`
116
- - **stdout** (`str`): Standard output of the command.
117
- - **stderr** (`str`): Standard error of the command.
118
- - **return_code** (`int`): Exit status of the command.
119
-
120
- On failure:
121
- `(False, error_message)` — a string describing the error.
119
+ - On success:
120
+ `(True, (stdout, stderr, return_code))`
121
+ - **stdout** (`str`): Standard output of the command (decoded to text).
122
+ - **stderr** (`str`): Standard error of the command (decoded to text).
123
+ - **return_code** (`int`): Exit status of the command.
124
+ - On failure:
125
+ `(False, error_message)` — a string describing the error.
122
126
 
123
127
  ### Notes
124
- - Output is always forced to English by setting `LC_ALL=C`.
125
- - On Windows, the command is prepended with `chcp 65001 &&` to ensure UTF-8 output.
126
- - If `shell=False` and the command contains pipes (`|`), it creates a manual pipeline.
127
- - Exceptions such as `OSError`, `ValueError`, or general execution errors are caught and
128
- reported.
128
+ - The environment is merged with `env` and always includes `LC_ALL=<lc_all>`, forcing output
129
+ to the specified locale.
130
+ - On Windows (`os.name == 'nt'`), `cmd` is automatically prefixed with `chcp 65001 &&` to
131
+ switch to UTF-8 code page, and `shell` is set to True.
132
+ - If `shell=False` and `cmd` contains pipes (`|`), the function splits `cmd` on `|` and
133
+ creates a pipeline of subprocesses. Each segment is run without a shell, with stdout of
134
+ one feeding stdin of the next.
135
+ - If `shell=True` or `stdin` is provided, the command is executed in a single shell
136
+ invocation (`subprocess.Popen(..., shell=True)`). The provided `stdin` string is passed
137
+ to `communicate()`.
138
+ - Exceptions such as `OSError`, `ValueError`, or other execution errors during process
139
+ creation are caught and reported as `(False, <error message>)`.
140
+ - If the process exceeds the specified `timeout`, it is killed, and the function returns
141
+ `(False, "Timeout after <timeout> seconds.")`.
129
142
  """
130
143
  env = {**os.environ.copy(), **(env or {})}
131
- env['LC_ALL'] = 'C'
144
+ env['LC_ALL'] = lc_all
132
145
 
133
146
  if os.name == 'nt':
134
147
  cmd = f'chcp 65001 && {cmd}'
@@ -15,7 +15,7 @@ The functions "to_text()" and "to_bytes()" are copied from
15
15
  """
16
16
 
17
17
  __author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
18
- __version__ = '2025051301'
18
+ __version__ = '2025053101'
19
19
 
20
20
  import codecs
21
21
  import re
@@ -180,22 +180,22 @@ def filter_mltext(_input, ignore):
180
180
  >>> filter_mltext('abcde', 'a') # "ignore" has to be a list
181
181
  ''
182
182
 
183
- >>> s = 'Lorem ipsum\n\ndolor sit amet\n\nconsectetur adipisicing'
183
+ >>> s = 'Lorem ipsum\\n\\ndolor sit amet\\n\\nconsectetur adipisicing'
184
184
  >>> filter_mltext(s, ['ipsum'])
185
- '\ndolor sit amet\n\nconsectetur adipisicing\n'
185
+ '\\ndolor sit amet\\n\\nconsectetur adipisicing\\n'
186
186
 
187
187
  >>> filter_mltext(s, ['dol'])
188
- 'Lorem ipsum\n\n\nconsectetur adipisicing\n'
188
+ 'Lorem ipsum\\n\\n\\nconsectetur adipisicing\\n'
189
189
 
190
190
  >>> filter_mltext(s, ['Dol'])
191
- 'Lorem ipsum\n\ndolor sit amet\n\nconsectetur adipisicing\n'
191
+ 'Lorem ipsum\\n\\ndolor sit amet\\n\\nconsectetur adipisicing\\n'
192
192
 
193
193
  >>> filter_mltext(s, ['d'])
194
- 'Lorem ipsum\n\n\n'
194
+ 'Lorem ipsum\\n\\n\\n'
195
195
 
196
196
  >>> s = 'Lorem ipsum'
197
197
  >>> filter_mltext(s, ['Dol'])
198
- 'Lorem ipsum\n'
198
+ 'Lorem ipsum\\n'
199
199
 
200
200
  >>> filter_mltext(s, ['ipsum'])
201
201
  ''
@@ -254,7 +254,7 @@ def mltext2array(_input, skip_header=False, sort_key=-1):
254
254
  - **list of list**: A list where each inner list represents a line split by whitespace.
255
255
 
256
256
  ### Example
257
- >>> s = '1662130953 timedatex\n1662130757 python3-pip-wheel\n1662130975 python3-dateutil'
257
+ >>> s = '1662130953 timedatex\\n1662130757 python3-pip-wheel\\n1662130975 python3-dateutil'
258
258
 
259
259
  >>> mltext2array(s, skip_header=False, sort_key=0)
260
260
  [['1662130757', 'python3-pip-wheel'], ['1662130953', 'timedatex'], ['1662130975', 'python3-dateutil']]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes