openSUSE Commits
Threads by month
- ----- 2024 -----
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
May 2018
- 1 participants
- 1987 discussions
Hello community,
here is the log from the commit of package YODA for openSUSE:Factory checked in at 2018-05-30 12:23:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/YODA (Old)
and /work/SRC/openSUSE:Factory/.YODA.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "YODA"
Wed May 30 12:23:07 2018 rev:11 rq:612675 version:1.7.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/YODA/YODA.changes 2017-08-24 18:45:06.003082908 +0200
+++ /work/SRC/openSUSE:Factory/.YODA.new/YODA.changes 2018-05-30 13:07:58.455770873 +0200
@@ -1,0 +2,51 @@
+Wed May 23 08:17:39 UTC 2018 - badshah400(a)gmail.com
+
+- Update to version 1.7.0:
+ * Add Nentries printout to yodals -v
+ * Patches for ROOT conversion from Robert Hatcher -- thanks!
+ * Add YODA format version annotation, at version 2, and update
+ YODA reader to use version info and multiline YAML EOF marker.
+ * Write YODA annotations in YAML with a --- YAML break-line.
+ * Enable compressed writing from Python.
+ * Remove UNUSED macro in favour of anonymous args.
+ * Enable zipped writing... but only works from C++ so far.
+ * Add HistoBin2D::area(), and provide a default normto=1.0
+ argument on the Python Histo2D.normalize() method.
+ * Change license explicitly to GPLv3, cf. MCnet3 agreement.
+ * Parse YODA format AO headers as YAML (restriction to
+ single-line dict entries for now).
+ * Use a slightly enhanced fast numeric parser in ReaderYODA
+ (taken from LHAPDF, originally inspired by Gavin Salam).
+ * Add an UNSCALE spec option to yodascale, to undo ScaledBy
+ effects.
+ * Add optional zlib support via zstr
+ * Fix setVal(i, x) numbered-axis methods on Point2D and Point3D:
+ switch break statements were missing.
+ * Explicitly load all ROOT objects as a list rather than
+ generator. Patch from Dmitry Kalinkin.
+ * Improvements to yodaplot, including two operating modes: the
+ default CMP mode is suitable for plotting histos by path, from
+ raw .yoda files.
+ * Update yoda.plotting functions to treat plot-keys as args and
+ AO annotations via case-insensitive keys.
+ * Add annotationsDict to the Python AO interface.
+ * Add AO as an alias for AnalysisObject.
+ * Add parallel/compatibility yoda1 package to aid eventual
+ transition to YODA v2.
+ * Add x,y,zMins and Maxs to all 1D data types and scatters (and
+ x,yMin/Max to the scatters) -- Python interface only.
+ * Rework some of the yoda.plotting tools, making it a bit more
+ compatible with user-scripted matplotlib.
+ * Add convenience aliases H1D, H2D, P1D, P2D, and S1D, S2D, S3D
+ for the HistoXD, ProfileXD, and ScatterXD classes
+ respectively.
+ * Add xyVals/Errs and other 'bin array property' accessors to
+ the Python Histo1D and Profile1D types: important for
+ connection to matplotlib.
+ * Use Python natsort library to sort yodals output if available.
+- Rebase sover.diff.
+- Add BuildRequires: pkgconfig(zlib); now required for bulding
+ YODA.
+- Fix env-based hashbangs.
+
+-------------------------------------------------------------------
Old:
----
YODA-1.6.7.tar.bz2
New:
----
YODA-1.7.0.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ YODA.spec ++++++
--- /var/tmp/diff_new_pack.06pBfv/_old 2018-05-30 13:07:59.107746291 +0200
+++ /var/tmp/diff_new_pack.06pBfv/_new 2018-05-30 13:07:59.111746140 +0200
@@ -1,7 +1,7 @@
#
# spec file for package YODA
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,13 +16,13 @@
#
-%define so_name lib%{name}-1_6_7
+%define so_name lib%{name}-1_7_0
Name: YODA
-Version: 1.6.7
+Version: 1.7.0
Release: 0
Summary: A small set of data analysis classes for MC event generator validation analyses
-License: GPL-2.0
+License: GPL-2.0-only
Group: Development/Libraries/C and C++
Url: http://yoda.hepforge.org/
Source: http://www.hepforge.org/archive/yoda/%{name}-%{version}.tar.bz2
@@ -37,6 +37,7 @@
BuildRequires: pkg-config
BuildRequires: python-Cython
BuildRequires: python-devel
+BuildRequires: pkgconfig(zlib)
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
@@ -120,6 +121,13 @@
# Remove traces of BUILDROOT from files
sed -i "s|%{buildroot}||g" %{buildroot}%{python_sitearch}/yoda/*.pyc
+# FIX env BASED HASHBANGS
+for exe in %{buildroot}%{_bindir}/*
+do
+ sed -E -i "s|^#! /usr/bin/env python|#! /usr/bin/python|" ${exe}
+done
+sed -E -i "s|^#! /usr/bin/env bash|#! /bin/bash|" %{buildroot}%{_bindir}/yoda-config
+
%post -n %{so_name} -p /sbin/ldconfig
%postun -n %{so_name} -p /sbin/ldconfig
@@ -153,6 +161,7 @@
%files -n python-%{name}
%defattr(-,root,root)
%{python_sitearch}/yoda/
+%{python_sitearch}/yoda1/
%{python_sitearch}/yoda*.egg-info
%changelog
++++++ YODA-1.6.7.tar.bz2 -> YODA-1.7.0.tar.bz2 ++++++
++++ 141195 lines of diff (skipped)
++++++ sover.diff ++++++
--- /var/tmp/diff_new_pack.06pBfv/_old 2018-05-30 13:08:00.819681741 +0200
+++ /var/tmp/diff_new_pack.06pBfv/_new 2018-05-30 13:08:00.823681590 +0200
@@ -2,15 +2,16 @@
src/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
-Index: YODA-1.6.5/src/Makefile.am
+Index: YODA-1.7.0/src/Makefile.am
===================================================================
---- YODA-1.6.5.orig/src/Makefile.am
-+++ YODA-1.6.5/src/Makefile.am
-@@ -23,6 +23,6 @@ libYODA_la_SOURCES = \
+--- YODA-1.7.0.orig/src/Makefile.am
++++ YODA-1.7.0/src/Makefile.am
+@@ -23,7 +23,7 @@ libYODA_la_SOURCES = \
+ Scatter2D.cc \
Scatter3D.cc
-
-libYODA_la_LDFLAGS = -avoid-version
+libYODA_la_LDFLAGS = -release ${PACKAGE_VERSION}
- libYODA_la_LIBADD = tinyxml/libtinyxml.la
- libYODA_la_CPPFLAGS = $(AM_CPPFLAGS) -DTIXML_USE_STL
+ libYODA_la_LIBADD = $(builddir)/tinyxml/libyoda-tinyxml.la $(builddir)/yamlcpp/libyoda-yaml-cpp.la
+ libYODA_la_CPPFLAGS = $(AM_CPPFLAGS) -DTIXML_USE_STL -I$(srcdir)/yamlcpp -I$(srcdir) -DYAMLCPP_API=3 -DYAML_NAMESPACE=YODA_YAML
+
1
0
Hello community,
here is the log from the commit of package ShellCheck for openSUSE:Factory checked in at 2018-05-30 12:21:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ShellCheck (Old)
and /work/SRC/openSUSE:Factory/.ShellCheck.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ShellCheck"
Wed May 30 12:21:42 2018 rev:10 rq:609837 version:0.4.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/ShellCheck/ShellCheck.changes 2018-04-17 11:18:24.483906523 +0200
+++ /work/SRC/openSUSE:Factory/.ShellCheck.new/ShellCheck.changes 2018-05-30 13:07:55.839869495 +0200
@@ -1,0 +2,30 @@
+Wed May 16 14:36:30 UTC 2018 - psimons(a)suse.com
+
+- Update to version v0.4.7-106-g235bf66 from Github to fix the
+ build with GHC 8.4.x.
+
+ * Added:
+ SC2232: Warn about invalid arguments to sudo
+ SC2231: Suggest quoting expansions in for loop globs
+ SC2229: Warn about 'read $var'
+ SC2227: Warn about redirections in the middle of 'find' commands
+ SC2224,SC2225,SC2226: Warn when using mv/cp/ln without a destination
+ SC2223: Quote warning specific to : ${var=value}
+ SC1131: Warn when using elseif or elsif
+ SC1128: Warn about blanks/comments before shebang
+ SC1127: Warn about C-style comments
+
+ * Fixed:
+ Annotations intended for a command's here documents now work
+ Escaped characters inside groups in =~ regexes now parse
+ Associative arrays are now respected in arithmetic contexts
+ SC1087 about $var[@] now correctly triggers on any index
+ Bad expansions in here documents are no longer ignored
+ FD move operations like {fd}>1- now parse correctly
+
+ * Changed:
+ SC1073: 'else if' is now parsed correctly and not like 'elif'
+ SC2163: 'export $name' can now be silenced with 'export ${name?}'
+ SC2183: Now warns when printf arg count is not a multiple of format count
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ ShellCheck.spec ++++++
--- /var/tmp/diff_new_pack.DTPXjo/_old 2018-05-30 13:07:56.539843107 +0200
+++ /var/tmp/diff_new_pack.DTPXjo/_new 2018-05-30 13:07:56.543842956 +0200
@@ -25,7 +25,7 @@
License: GPL-3.0-or-later
Group: Development/Libraries/Haskell
URL: https://hackage.haskell.org/package/%{name}
-Source0: https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.t…
+Source0: https://github.com/koalaman/shellcheck/archive/v0.4.7-106-g235bf66.tar.gz#/…
Source1: https://hackage.haskell.org/package/%{name}-%{version}/revision/1.cabal#/%{…
BuildRequires: ghc-Cabal-devel
BuildRequires: ghc-QuickCheck-devel
@@ -37,6 +37,7 @@
BuildRequires: ghc-process-devel
BuildRequires: ghc-regex-tdfa-devel
BuildRequires: ghc-rpm-macros
+BuildRequires: pandoc
%description
The goals of ShellCheck are:
@@ -69,14 +70,14 @@
This package provides the Haskell %{name} library development files.
%prep
-%setup -q
-cp -p %{SOURCE1} %{name}.cabal
+%setup -q -n shellcheck-235bf6605fed31c90b17f3f76a30945ef344d015
%build
%ghc_lib_build
%install
%ghc_lib_install
+pandoc -s -t man shellcheck.1.md -o shellcheck.1
install -Dpm 0644 shellcheck.1 %{buildroot}%{_mandir}/man1/shellcheck.1
%check
@@ -89,13 +90,13 @@
%ghc_pkg_recache
%files
-%doc LICENSE
+%license LICENSE
%doc README.md
%{_bindir}/shellcheck
-%{_mandir}/man1/shellcheck.1*
+%{_mandir}/man1/shellcheck.1%{?ext_man}
%files -n ghc-%{name} -f ghc-%{name}.files
-%doc LICENSE
+%license LICENSE
%files -n ghc-%{name}-devel -f ghc-%{name}-devel.files
%doc README.md
++++++ ShellCheck-0.4.7.tar.gz ++++++
++++ 21542 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package NetworkManager-openvpn for openSUSE:Factory checked in at 2018-05-30 12:23:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/NetworkManager-openvpn (Old)
and /work/SRC/openSUSE:Factory/.NetworkManager-openvpn.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "NetworkManager-openvpn"
Wed May 30 12:23:14 2018 rev:75 rq:612862 version:1.8.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/NetworkManager-openvpn/NetworkManager-openvpn.changes 2018-05-16 11:41:26.988612778 +0200
+++ /work/SRC/openSUSE:Factory/.NetworkManager-openvpn.new/NetworkManager-openvpn.changes 2018-05-30 13:07:48.244155798 +0200
@@ -1,0 +2,9 @@
+Mon May 28 16:09:38 UTC 2018 - bjorn.lie(a)gmail.com
+
+- Update to version 1.8.4:
+ + Add support for the crl-verify option (bgo#782309)
+ + Fix termination of openvpn process upon disconnect
+ (rh#1576600).
+ + Updated translations.
+
+-------------------------------------------------------------------
Old:
----
NetworkManager-openvpn-1.8.2.tar.xz
New:
----
NetworkManager-openvpn-1.8.4.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ NetworkManager-openvpn.spec ++++++
--- /var/tmp/diff_new_pack.13MLFW/_old 2018-05-30 13:07:48.672139669 +0200
+++ /var/tmp/diff_new_pack.13MLFW/_new 2018-05-30 13:07:48.676139518 +0200
@@ -17,7 +17,7 @@
Name: NetworkManager-openvpn
-Version: 1.8.2
+Version: 1.8.4
Release: 0
Summary: NetworkManager VPN support for OpenVPN
License: GPL-2.0-or-later
++++++ NetworkManager-openvpn-1.8.2.tar.xz -> NetworkManager-openvpn-1.8.4.tar.xz ++++++
++++ 20133 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package 000product for openSUSE:Factory checked in at 2018-05-30 12:24:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/000product (Old)
and /work/SRC/openSUSE:Factory/.000product.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "000product"
Wed May 30 12:24:22 2018 rev:243 rq: version:unknown
Wed May 30 12:24:21 2018 rev:242 rq: version:unknown
Changes:
--------
New Changes file:
NO CHANGES FILE!!!
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
_service:product_converter:openSUSE-Addon-NonOss-ftp-ftp-i586_x86_64.kiwi: same change
_service:product_converter:openSUSE-Addon-NonOss-release.spec: same change
++++++ _service:product_converter:openSUSE-Tumbleweed-Kubic-dvd5-dvd-x86_64.kiwi ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:40.960430249 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:40.964430099 +0200
@@ -1,4 +1,4 @@
-<image name="OBS__openSUSE-Tumbleweed-Kubic___20180529" schemaversion="4.1">
+<image name="OBS__openSUSE-Tumbleweed-Kubic___20180530" schemaversion="4.1">
<description type="system">
<author>The SUSE Team</author>
<contact>build(a)opensuse.org</contact>
@@ -35,9 +35,9 @@
<productvar name="SEPARATE_MEDIA">true</productvar>
<productvar name="SHA1OPT">-x -2</productvar>
<productvar name="VENDOR">openSUSE</productvar>
- <productvar name="VERSION">20180529</productvar>
+ <productvar name="VERSION">20180530</productvar>
<productinfo name="CONTENTSTYLE">11</productinfo>
- <productinfo name="DISTRO">cpe:/o:opensuse:opensuse-tumbleweed-kubic:20180529,openSUSE Tumbleweed Kubic</productinfo>
+ <productinfo name="DISTRO">cpe:/o:opensuse:opensuse-tumbleweed-kubic:20180530,openSUSE Tumbleweed Kubic</productinfo>
<productinfo name="LINGUAS">en_US </productinfo>
<productinfo name="VENDOR">openSUSE</productinfo>
<productoption name="INI_DIR">/usr/share/kiwi/modules/plugins/suse-tumbleweed</productoption>
++++++ _service:product_converter:openSUSE-Tumbleweed-Kubic-release.spec ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:40.988429195 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:40.996428893 +0200
@@ -17,7 +17,7 @@
Name: openSUSE-Tumbleweed-Kubic-release
-Version: 20180529
+Version: 20180530
Release: 0
Summary: openSUSE Tumbleweed Kubic
License: GPL-2.0-or-later
@@ -38,9 +38,9 @@
ExclusiveArch: %ix86 x86_64 ppc64le s390x aarch64
Provides: %name-%version
Provides: product() = openSUSE-Tumbleweed-Kubic
-Provides: product(openSUSE-Tumbleweed-Kubic) = 20180529-0
+Provides: product(openSUSE-Tumbleweed-Kubic) = 20180530-0
Provides: product-label() = openSUSE%20Tumbleweed%20Kubic
-Provides: product-cpeid() = cpe%3A%2Fo%3Aopensuse%3Aopensuse%2Dtumbleweed%2Dkubic%3A20180529
+Provides: product-cpeid() = cpe%3A%2Fo%3Aopensuse%3Aopensuse%2Dtumbleweed%2Dkubic%3A20180530
Provides: product-url(releasenotes) = http%3A%2F%2Fdoc.opensuse.org%2Frelease%2Dnotes%2Fx86_64%2FopenSUSE%2FTumbleweed%2Frelease%2Dnotes%2DopenSUSE.rpm
Provides: product-endoflife()
Requires: product_flavor(openSUSE-Tumbleweed-Kubic)
@@ -61,7 +61,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(dvd)
-Provides: product_flavor(openSUSE-Tumbleweed-Kubic) = 20180529-0
+Provides: product_flavor(openSUSE-Tumbleweed-Kubic) = 20180530-0
Summary: openSUSE Tumbleweed Kubic
%description dvd
@@ -123,11 +123,11 @@
<product schemeversion="0">
<vendor>openSUSE</vendor>
<name>openSUSE-Tumbleweed-Kubic</name>
- <version>20180529</version>
+ <version>20180530</version>
<release>0</release>
<endoflife></endoflife>
<arch>%{_target_cpu}</arch>
- <cpeid>cpe:/o:opensuse:opensuse-tumbleweed-kubic:20180529</cpeid>
+ <cpeid>cpe:/o:opensuse:opensuse-tumbleweed-kubic:20180530</cpeid>
<productline>openSUSE-Tumbleweed-Kubic</productline>
<register>
<pool>
++++++ _service:product_converter:openSUSE-cd-mini-i586.kiwi ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:41.016428140 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:41.016428140 +0200
@@ -1,4 +1,4 @@
-<image name="OBS__openSUSE___20180529" schemaversion="4.1">
+<image name="OBS__openSUSE___20180530" schemaversion="4.1">
<description type="system">
<author>The SUSE Team</author>
<contact>build(a)opensuse.org</contact>
@@ -32,9 +32,9 @@
<productvar name="SEPARATE_MEDIA">true</productvar>
<productvar name="SHA1OPT">-x -2</productvar>
<productvar name="VENDOR">openSUSE</productvar>
- <productvar name="VERSION">20180529</productvar>
+ <productvar name="VERSION">20180530</productvar>
<productinfo name="CONTENTSTYLE">11</productinfo>
- <productinfo name="DISTRO">cpe:/o:opensuse:opensuse:20180529,openSUSE Tumbleweed</productinfo>
+ <productinfo name="DISTRO">cpe:/o:opensuse:opensuse:20180530,openSUSE Tumbleweed</productinfo>
<productinfo name="LINGUAS">cs da de en en_GB en_US es fi fr hu it ja nb nl pl pt pt_BR ru sv zh zh_CN zh_TW </productinfo>
<productinfo name="VENDOR">openSUSE</productinfo>
<productoption name="INI_DIR">/usr/share/kiwi/modules/plugins/suse-tumbleweed</productoption>
_service:product_converter:openSUSE-cd-mini-x86_64.kiwi: same change
_service:product_converter:openSUSE-dvd5-dvd-i586.kiwi: same change
_service:product_converter:openSUSE-dvd5-dvd-x86_64.kiwi: same change
++++++ _service:product_converter:openSUSE-ftp-ftp-i586_x86_64.kiwi ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:41.140423468 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:41.140423468 +0200
@@ -1,4 +1,4 @@
-<image name="OBS__openSUSE___20180529" schemaversion="4.1">
+<image name="OBS__openSUSE___20180530" schemaversion="4.1">
<description type="system">
<author>The SUSE Team</author>
<contact>build(a)opensuse.org</contact>
@@ -24,7 +24,7 @@
<productvar name="DISTNAME">openSUSE</productvar>
<productvar name="FLAVOR">ftp</productvar>
<productvar name="MAKE_LISTINGS">true</productvar>
- <productvar name="MEDIUM_NAME">openSUSE-20180529-i586-x86_64</productvar>
+ <productvar name="MEDIUM_NAME">openSUSE-20180530-i586-x86_64</productvar>
<productvar name="MULTIPLE_MEDIA">true</productvar>
<productvar name="PRODUCT_DIR">/</productvar>
<productvar name="PRODUCT_NAME">$DISTNAME-$FLAVOR</productvar>
@@ -36,9 +36,9 @@
<productvar name="SEPARATE_MEDIA">true</productvar>
<productvar name="SHA1OPT">-x -2</productvar>
<productvar name="VENDOR">openSUSE</productvar>
- <productvar name="VERSION">20180529</productvar>
+ <productvar name="VERSION">20180530</productvar>
<productinfo name="CONTENTSTYLE">11</productinfo>
- <productinfo name="DISTRO">cpe:/o:opensuse:opensuse:20180529,openSUSE Tumbleweed</productinfo>
+ <productinfo name="DISTRO">cpe:/o:opensuse:opensuse:20180530,openSUSE Tumbleweed</productinfo>
<productinfo name="LINGUAS">cs da de en en_GB en_US es fi fr hu it ja nb nl pl pt pt_BR ru sv zh zh_CN zh_TW </productinfo>
<productinfo name="VENDOR">openSUSE</productinfo>
<productoption name="DEBUGMEDIUM">2</productoption>
++++++ _service:product_converter:openSUSE-release.spec ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:41.176422112 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:41.200421208 +0200
@@ -20,7 +20,7 @@
#define betaversion %{nil}
%define codename Tumbleweed
Name: openSUSE-release
-Version: 20180529
+Version: 20180530
Release: 0
# 0 is the product release, not the build release of this package
Summary: openSUSE Tumbleweed
@@ -51,7 +51,7 @@
Obsoletes: aaa_version
Obsoletes: openSUSE-Promo-release <= 11.1
Obsoletes: openSUSE-release-live <= 11.0
-Obsoletes: product_flavor(%{product}) < 20180529
+Obsoletes: product_flavor(%{product}) < 20180530
# bnc#826592
Provides: weakremover(kernel-default) < 3.11
Provides: weakremover(kernel-desktop) < 4.2
@@ -61,7 +61,7 @@
Provides: weakremover(kernel-xen) < 3.11
Provides: %name-%version
Provides: product() = openSUSE
-Provides: product(openSUSE) = 20180529-0
+Provides: product(openSUSE) = 20180530-0
%ifarch x86_64
Provides: product-register-target() = openSUSE%2DTumbleweed%2Dx86_64
%endif
@@ -75,7 +75,7 @@
Provides: product-register-target() = openSUSE%2DTumbleweed%2Daarch64
%endif
Provides: product-label() = openSUSE
-Provides: product-cpeid() = cpe%3A%2Fo%3Aopensuse%3Aopensuse%3A20180529
+Provides: product-cpeid() = cpe%3A%2Fo%3Aopensuse%3Aopensuse%3A20180530
Provides: product-url(releasenotes) = http%3A%2F%2Fdoc.opensuse.org%2Frelease%2Dnotes%2Fx86_64%2FopenSUSE%2FTumbleweed%2Frelease%2Dnotes%2DopenSUSE.rpm
Provides: product-url(repository) = http%3A%2F%2Fdownload.opensuse.org%2Ftumbleweed%2Frepo%2Foss%2F
Requires: product_flavor(openSUSE)
@@ -17025,7 +17025,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(ftp)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description ftp
@@ -17040,7 +17040,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(mini)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description mini
@@ -17055,7 +17055,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(dvd)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description dvd
@@ -17070,7 +17070,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(livecd-kde)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description livecd-kde
@@ -17085,7 +17085,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(livecd-x11)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description livecd-x11
@@ -17100,7 +17100,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(livecd-gnome)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description livecd-gnome
@@ -17115,7 +17115,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(usb-kde)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description usb-kde
@@ -17130,7 +17130,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(usb-gnome)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description usb-gnome
@@ -17145,7 +17145,7 @@
Group: System/Fhs
Provides: product_flavor()
Provides: flavor(usb-x11)
-Provides: product_flavor(openSUSE) = 20180529-0
+Provides: product_flavor(openSUSE) = 20180530-0
Summary: openSUSE Tumbleweed
%description usb-x11
@@ -17218,10 +17218,10 @@
<product schemeversion="0">
<vendor>openSUSE</vendor>
<name>openSUSE</name>
- <version>20180529</version>
+ <version>20180530</version>
<release>0</release>
<arch>%{_target_cpu}</arch>
- <cpeid>cpe:/o:opensuse:opensuse:20180529</cpeid>
+ <cpeid>cpe:/o:opensuse:opensuse:20180530</cpeid>
<productline>openSUSE</productline>
<register>
<pool>
openSUSE-release.spec: same change
++++++ openSUSE-Tumbleweed-Kubic.product ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:41.572407193 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:41.572407193 +0200
@@ -6,7 +6,7 @@
<name>openSUSE-Tumbleweed-Kubic</name>
<releasepkgname>openSUSE-Tumbleweed-Kubic-release</releasepkgname>
<endoflife/>
- <version>20180529</version>
+ <version>20180530</version>
<!-- release is no longer optional -->
<release>0</release>
<productline>openSUSE-Tumbleweed-Kubic</productline>
++++++ openSUSE.product ++++++
--- /var/tmp/diff_new_pack.l0gKHB/_old 2018-05-30 13:07:41.588406591 +0200
+++ /var/tmp/diff_new_pack.l0gKHB/_new 2018-05-30 13:07:41.588406591 +0200
@@ -4,7 +4,7 @@
<product>
<vendor>openSUSE</vendor>
<name>openSUSE</name>
- <version>20180529</version>
+ <version>20180530</version>
<release>0</release>
<productline>openSUSE</productline>
1
0
Hello community,
here is the log from the commit of package youtube-dl for openSUSE:Factory checked in at 2018-05-30 12:23:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/youtube-dl (Old)
and /work/SRC/openSUSE:Factory/.youtube-dl.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "youtube-dl"
Wed May 30 12:23:28 2018 rev:77 rq:612893 version:2018.05.26
Changes:
--------
--- /work/SRC/openSUSE:Factory/youtube-dl/youtube-dl.changes 2018-05-19 15:43:52.259543988 +0200
+++ /work/SRC/openSUSE:Factory/.youtube-dl.new/youtube-dl.changes 2018-05-30 12:43:03.185892599 +0200
@@ -1,0 +2,8 @@
+Tue May 29 14:25:58 UTC 2018 - jengelh(a)inai.de
+
+- Update to new upstream release 2018.05.26
+ * imgur: Fix extraction
+ * hidive: add support for authentication
+ * nbc: add support for stream.nbcsports.com
+
+-------------------------------------------------------------------
Old:
----
youtube-dl-2018.05.18.tar.gz
youtube-dl-2018.05.18.tar.gz.sig
New:
----
youtube-dl-2018.05.26.tar.gz
youtube-dl-2018.05.26.tar.gz.sig
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-youtube-dl.spec ++++++
--- /var/tmp/diff_new_pack.GJ0jvj/_old 2018-05-30 12:43:04.033872281 +0200
+++ /var/tmp/diff_new_pack.GJ0jvj/_new 2018-05-30 12:43:04.037872184 +0200
@@ -19,7 +19,7 @@
%define modname youtube-dl
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-youtube-dl
-Version: 2018.05.18
+Version: 2018.05.26
Release: 0
Summary: A python module for downloading from video sites for offline watching
License: SUSE-Public-Domain AND CC-BY-SA-3.0
++++++ youtube-dl.spec ++++++
--- /var/tmp/diff_new_pack.GJ0jvj/_old 2018-05-30 12:43:04.097870745 +0200
+++ /var/tmp/diff_new_pack.GJ0jvj/_new 2018-05-30 12:43:04.101870649 +0200
@@ -17,7 +17,7 @@
Name: youtube-dl
-Version: 2018.05.18
+Version: 2018.05.26
Release: 0
Summary: A tool for downloading from video sites for offline watching
License: SUSE-Public-Domain AND CC-BY-SA-3.0
++++++ youtube-dl-2018.05.18.tar.gz -> youtube-dl-2018.05.26.tar.gz ++++++
++++ 2131 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package yast2-s390 for openSUSE:Factory checked in at 2018-05-30 12:23:55
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-s390 (Old)
and /work/SRC/openSUSE:Factory/.yast2-s390.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-s390"
Wed May 30 12:23:55 2018 rev:6 rq:612946 version:4.0.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-s390/yast2-s390.changes 2018-03-22 12:12:16.678273538 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-s390.new/yast2-s390.changes 2018-05-30 12:42:58.933994171 +0200
@@ -1,0 +2,6 @@
+Tue May 08 14:01:56 CEST 2018 - aschnell(a)suse.com
+
+- disable mdadm auto assemble during DASD dialog (bsc#1089645)
+- 4.0.4
+
+-------------------------------------------------------------------
Old:
----
yast2-s390-4.0.3.tar.bz2
New:
----
yast2-s390-4.0.4.tar.bz2
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast2-s390.spec ++++++
--- /var/tmp/diff_new_pack.VLzEvp/_old 2018-05-30 12:42:59.361983969 +0200
+++ /var/tmp/diff_new_pack.VLzEvp/_new 2018-05-30 12:42:59.365983874 +0200
@@ -17,7 +17,7 @@
Name: yast2-s390
-Version: 4.0.3
+Version: 4.0.4
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -29,6 +29,11 @@
BuildRequires: yast2-ruby-bindings >= 3.1.7
BuildRequires: rubygem(%rb_default_ruby_abi:rspec)
BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake)
+
+# Y2Storage::Inhibitors
+BuildRequires: yast2-storage-ng >= 4.0.175
+Requires: yast2-storage-ng >= 4.0.175
+
ExclusiveArch: s390 s390x
Requires: s390-tools
Requires: yast2
++++++ yast2-s390-4.0.3.tar.bz2 -> yast2-s390-4.0.4.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.0.3/README.md new/yast2-s390-4.0.4/README.md
--- old/yast2-s390-4.0.3/README.md 2018-03-21 16:50:17.000000000 +0100
+++ new/yast2-s390-4.0.4/README.md 2018-05-29 10:32:44.000000000 +0200
@@ -3,3 +3,10 @@
[![Travis Build](https://travis-ci.org/yast/yast-s390.svg?branch=master)](https://tra…
[![Code Coverage Status](
https://coveralls.io/repos/github/yast/yast-s390/badge.svg?branch=master)](…)
+
+## Resources
+
+For s390 development these resources are used:
+
+- https://www.ibm.com/developerworks/linux/linux390/documentation_dev.html
+- https://www.ibm.com/developerworks/linux/linux390/documentation_suse.html (for released products)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.0.3/package/yast2-s390.changes new/yast2-s390-4.0.4/package/yast2-s390.changes
--- old/yast2-s390-4.0.3/package/yast2-s390.changes 2018-03-21 16:50:17.000000000 +0100
+++ new/yast2-s390-4.0.4/package/yast2-s390.changes 2018-05-29 10:32:44.000000000 +0200
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Tue May 08 14:01:56 CEST 2018 - aschnell(a)suse.com
+
+- disable mdadm auto assemble during DASD dialog (bsc#1089645)
+- 4.0.4
+
+-------------------------------------------------------------------
Tue Mar 20 15:12:15 UTC 2018 - jreidinger(a)suse.com
- Improve error reporting and logging when underlying scripts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.0.3/package/yast2-s390.spec new/yast2-s390-4.0.4/package/yast2-s390.spec
--- old/yast2-s390-4.0.3/package/yast2-s390.spec 2018-03-21 16:50:17.000000000 +0100
+++ new/yast2-s390-4.0.4/package/yast2-s390.spec 2018-05-29 10:32:44.000000000 +0200
@@ -17,7 +17,7 @@
Name: yast2-s390
-Version: 4.0.3
+Version: 4.0.4
Release: 0
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -31,6 +31,11 @@
BuildRequires: rubygem(%rb_default_ruby_abi:rspec)
BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake)
BuildRequires: update-desktop-files
+
+# Y2Storage::Inhibitors
+BuildRequires: yast2-storage-ng >= 4.0.175
+Requires: yast2-storage-ng >= 4.0.175
+
ExclusiveArch: s390 s390x
Requires: yast2
Requires: yast2-ruby-bindings >= 3.1.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.0.3/src/include/s390/dasd/wizards.rb new/yast2-s390-4.0.4/src/include/s390/dasd/wizards.rb
--- old/yast2-s390-4.0.3/src/include/s390/dasd/wizards.rb 2018-03-21 16:50:17.000000000 +0100
+++ new/yast2-s390-4.0.4/src/include/s390/dasd/wizards.rb 2018-05-29 10:32:44.000000000 +0200
@@ -24,6 +24,9 @@
# Summary: Wizards definitions
# Authors: Jiri Srain <jsrain(a)suse.cz>
#
+
+require "y2storage/inhibitors"
+
module Yast
module S390DasdWizardsInclude
def initialize_s390_dasd_wizards(include_target)
@@ -80,7 +83,13 @@
Wizard.CreateDialog
Wizard.SetDesktopIcon("dasd")
- ret = Sequencer.Run(aliases, sequence)
+ begin
+ inhibitors = Y2Storage::Inhibitors.new
+ inhibitors.inhibit
+ ret = Sequencer.Run(aliases, sequence)
+ ensure
+ inhibitors.uninhibit
+ end
Wizard.CloseDialog
1
0
Hello community,
here is the log from the commit of package yast-gpmc for openSUSE:Factory checked in at 2018-05-30 12:23:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast-gpmc (Old)
and /work/SRC/openSUSE:Factory/.yast-gpmc.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast-gpmc"
Wed May 30 12:23:51 2018 rev:2 rq:612934 version:1.3.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/yast-gpmc/yast-gpmc.changes 2017-11-29 10:53:51.482042237 +0100
+++ /work/SRC/openSUSE:Factory/.yast-gpmc.new/yast-gpmc.changes 2018-05-30 12:42:50.758178382 +0200
@@ -1,0 +2,5 @@
+Tue May 29 20:12:50 UTC 2018 - dmulder(a)suse.com
+
+- v1.3.1: Lots of improvements and fixes, py3 compatability, etc.
+
+-------------------------------------------------------------------
Old:
----
yast-gpmc-1.0.tar.gz
New:
----
yast-gpmc-1.3.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ yast-gpmc.spec ++++++
--- /var/tmp/diff_new_pack.tqNUCk/_old 2018-05-30 12:42:51.522162074 +0200
+++ /var/tmp/diff_new_pack.tqNUCk/_new 2018-05-30 12:42:51.526161989 +0200
@@ -1,7 +1,7 @@
#
# spec file for package yast-gpmc
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
Name: yast-gpmc
-Version: 1.0
+Version: 1.3.1
Release: 0
Summary: Group Policy Management Console for YaST
License: GPL-3.0
@@ -26,6 +26,7 @@
Source: %{name}-%{version}.tar.gz
BuildArch: noarch
Requires: krb5-client
+Requires: python-configparser
Requires: python-ldap
Requires: samba-client
Requires: samba-python
++++++ yast-gpmc-1.0.tar.gz -> yast-gpmc-1.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/.gitignore new/yast-gpmc-1.3.1/.gitignore
--- old/yast-gpmc-1.0/.gitignore 2017-11-08 19:20:04.000000000 +0100
+++ new/yast-gpmc-1.3.1/.gitignore 2018-05-29 20:44:25.000000000 +0200
@@ -9,3 +9,4 @@
autom4te.cache
*.pyc
src/gpmc.desktop
+src/gpmc.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/configure.ac new/yast-gpmc-1.3.1/configure.ac
--- old/yast-gpmc-1.0/configure.ac 2017-11-08 19:20:04.000000000 +0100
+++ new/yast-gpmc-1.3.1/configure.ac 2018-05-29 20:44:25.000000000 +0200
@@ -5,6 +5,7 @@
AC_INIT([yast2-gpmc],[1.0],[http://bugs.opensuse.org/],[yast2-gpmc])
AM_INIT_AUTOMAKE
+AM_PATH_PYTHON([2.7])
dnl Checks for programs.
AC_PROG_INSTALL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/package/yast-gpmc.spec new/yast-gpmc-1.3.1/package/yast-gpmc.spec
--- old/yast-gpmc-1.0/package/yast-gpmc.spec 1970-01-01 01:00:00.000000000 +0100
+++ new/yast-gpmc-1.3.1/package/yast-gpmc.spec 2018-05-29 20:44:25.000000000 +0200
@@ -0,0 +1,59 @@
+#
+# spec file for package yast-gpmc
+#
+
+Name: yast-gpmc
+Version: 1.0
+Release: 1
+License: GPL-3.0
+Summary: Group Policy Management Console for YaST
+Url: http://www.github.com/dmulder/yast-gpmc
+Group: Productivity/Networking/Samba
+Source: %{name}-%{version}.tar.gz
+BuildArch: noarch
+Requires: yast2-python-bindings >= 4.0.0
+Requires: samba-client
+Requires: python-ldap
+Requires: samba-python
+Requires: krb5-client
+Requires: yast2
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: python
+BuildRequires: perl-XML-Writer
+BuildRequires: update-desktop-files
+BuildRequires: yast2
+BuildRequires: yast2-devtools
+BuildRequires: yast2-testsuite
+
+%description
+The Group Policy Management console for YaST provides tools for creating and
+modifying Group Policy Objects in Active Directory.
+
+%prep
+%setup -q
+
+%build
+autoreconf -if
+%configure --prefix=%{_prefix}
+make
+
+%install
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%clean
+%{__rm} -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%dir %{_datadir}/YaST2/include/gpmc
+%{_datadir}/YaST2/clients/gpmc.py
+%{_datadir}/YaST2/include/gpmc/complex.py
+%{_datadir}/YaST2/include/gpmc/dialogs.py
+%{_datadir}/YaST2/include/gpmc/wizards.py
+%{_datadir}/YaST2/include/gpmc/defaults.py
+%{_datadir}/applications/YaST2/gpmc.desktop
+%dir %{_datadir}/doc/yast2-gpmc
+%{_datadir}/doc/yast2-gpmc/COPYING
+
+%changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/Makefile.am new/yast-gpmc-1.3.1/src/Makefile.am
--- old/yast-gpmc-1.0/src/Makefile.am 2017-11-08 19:20:04.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/Makefile.am 2018-05-29 20:44:25.000000000 +0200
@@ -22,9 +22,13 @@
moduledir = ${prefix}/share/YaST2/modules
+gpmc.py: gpmc.py.in
+ sed -e 's;[@]INCLUDEDIR[@];$(yncludedir);g' < $(srcdir)/gpmc.py.in > $(srcdir)/gpmc.py
+
# create a symlink for local build, #145327
gpmc:
ln -sf . $@
ycpchook = gpmc
EXTRA_DIST = $(client_DATA) $(ynclude_DATA) $(module_DATA) $(desktop_DATA)
+CLEANFILES = gpmc.py gpmc.desktop
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/complex.py new/yast-gpmc-1.3.1/src/complex.py
--- old/yast-gpmc-1.0/src/complex.py 2017-11-17 16:10:53.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/complex.py 2018-05-29 20:44:25.000000000 +0200
@@ -1,7 +1,8 @@
+from __future__ import absolute_import, division, print_function, unicode_literals
import ldap, ldap.modlist, ldap.sasl
from samba import smb
-from ConfigParser import ConfigParser
-from StringIO import StringIO
+from configparser import ConfigParser
+from io import StringIO
import xml.etree.ElementTree as etree
import os.path, sys
from samba.net import Net
@@ -11,30 +12,185 @@
from ldap.modlist import addModlist as addlist
from ldap.modlist import modifyModlist as modlist
import re
+import traceback
+import ldb
+from samba.dcerpc import security
+from samba.ndr import ndr_unpack
+import samba.security
+from samba.ntacls import dsacl2fsacl
+
+PY3 = sys.version_info[0] == 3
+PY2 = sys.version_info[0] == 2
+
+class LdapException(Exception):
+ def __init__(self, *args, **kwargs):
+ Exception.__init__(self, *args, **kwargs)
+ if len(self.args) > 0:
+ self.msg = self.args[0]
+ else:
+ self.msg = None
+ if len(self.args) > 1:
+ self.info = self.args[1]
+ else:
+ self.info = None
+
+def _ldap_exc_msg(e):
+ if len(e.args) > 0 and \
+ type(e.args[-1]) is dict and \
+ 'desc' in e.args[-1]:
+ return e.args[-1]['desc']
+ else:
+ return str(e)
+
+def _ldap_exc_info(e):
+ if len(e.args) > 0 and \
+ type(e.args[-1]) is dict and \
+ 'info' in e.args[-1]:
+ return e.args[-1]['info']
+ else:
+ return ''
+
+def ldap_search(l, *args):
+ try:
+ return l.search_s(*args)
+ except Exception as e:
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.search_s: %s\n' % _ldap_exc_msg(e))
+
+def ldap_add(l, *args):
+ try:
+ return l.add_s(*args)
+ except Exception as e:
+ raise LdapException(_ldap_exc_msg(e), _ldap_exc_info(e))
+
+def ldap_modify(l, *args):
+ try:
+ return l.modify(*args)
+ except Exception as e:
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.modify: %s\n' % _ldap_exc_msg(e))
+
+def ldap_delete(l, *args):
+ try:
+ return l.delete_s(*args)
+ except Exception as e:
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.delete_s: %s\n' % _ldap_exc_msg(e))
+
+def open_bytes(filename):
+ if PY3:
+ return open(filename, errors='ignore')
+ else:
+ return open(filename, 'rb')
+
+def dict_to_bytes(d):
+ for key in d.keys():
+ if type(d[key]) is dict:
+ d[key] = dict_to_bytes(d[key])
+ elif type(d[key]) is list:
+ vals = []
+ for val in d[key]:
+ if type(val) is str:
+ vals.append(val.encode('utf-8'))
+ else:
+ vals.append(val)
+ d[key] = vals
+ elif type(d[key]) is str:
+ d[key] = d[key].encode('utf-8')
+ return d
+
+def stringify_ldap(data):
+ if type(data) == dict:
+ for key, value in data.items():
+ data[key] = stringify_ldap(value)
+ return data
+ elif type(data) == list:
+ new_list = []
+ for item in data:
+ new_list.append(stringify_ldap(item))
+ return new_list
+ elif type(data) == tuple:
+ new_tuple = []
+ for item in data:
+ new_tuple.append(stringify_ldap(item))
+ return tuple(new_tuple)
+ elif PY2 and type(data) == unicode:
+ return str(data)
+ elif PY3 and type(data) == bytes:
+ try:
+ return data.decode('utf-8')
+ except UnicodeDecodeError:
+ return data
+ else:
+ return data
+
+def parse_unc(unc):
+ '''Parse UNC string into a hostname, a service, and a filepath'''
+ if unc.startswith('\\\\') and unc.startswith('//'):
+ raise ValueError("UNC doesn't start with \\\\ or //")
+ tmp = unc[2:].split('/', 2)
+ if len(tmp) == 3:
+ return tmp
+ tmp = unc[2:].split('\\', 2)
+ if len(tmp) == 3:
+ return tmp
+ raise ValueError("Invalid UNC string: %s" % unc)
+
+def dn_to_path(realm, dn):
+ base_dn = (','.join(['DC=%s' % part for part in realm.lower().split('.')])).encode('utf-8')
+ parts = [p.split(b'=')[-1].title() for p in dn.lower().replace(base_dn.lower(), b'').split(b',') if p]
+ parts.append(realm.encode('utf-8'))
+ return b'/'.join(reversed(parts))
+
+def parse_gplink(gplink):
+ '''parse a gPLink into an array of dn and options'''
+ ret = {}
+ a = gplink.split(b']')
+ for g in a:
+ if not g:
+ continue
+ d = g.split(b';')
+ if len(d) != 2 or not d[0].startswith(b"[LDAP://"):
+ raise RuntimeError("Badly formed gPLink '%s'" % g)
+ options = bin(int(d[1]))[2:].zfill(2)
+ name = d[0][8:].split(b',')[0][3:].decode()
+ ret[name] = {'enforced' : 'Yes' if int(options[-2]) else 'No', 'enabled' : 'No' if int(options[-1]) else 'Yes', 'dn' : d[0][8:].decode(), 'options' : int(d[1])}
+ return ret
+
+def encode_gplink(gplist):
+ '''Encode an array of dn and options into gPLink string'''
+ ret = ''
+ for g in gplist:
+ ret += "[LDAP://%s;%d]" % (g['dn'], g['options'])
+ return ret
class GPConnection:
def __init__(self, lp, creds):
self.lp = lp
self.creds = creds
- self.realm = lp.get('realm')
net = Net(creds=creds, lp=lp)
- cldap_ret = net.finddc(domain=self.realm, flags=(nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS))
+ cldap_ret = net.finddc(domain=lp.get('realm'), flags=(nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS | nbt.NBT_SERVER_WRITABLE))
+ self.realm = cldap_ret.dns_domain
+ self.dc_hostname = cldap_ret.pdc_dns_name
self.l = ldap.initialize('ldap://%s' % cldap_ret.pdc_dns_name)
if self.__kinit_for_gssapi():
auth_tokens = ldap.sasl.gssapi('')
self.l.sasl_interactive_bind_s('', auth_tokens)
else:
self.l.bind_s('%s@%s' % (creds.get_username(), self.realm) if not self.realm in creds.get_username() else creds.get_username(), creds.get_password())
+ self.l.set_option(ldap.OPT_REFERRALS,0)
def __kinit_for_gssapi(self):
p = Popen(['kinit', '%s@%s' % (self.creds.get_username(), self.realm) if not self.realm in self.creds.get_username() else self.creds.get_username()], stdin=PIPE, stdout=PIPE)
- p.stdin.write('%s\n' % self.creds.get_password())
+ p.stdin.write(('%s\n'%self.creds.get_password()).encode())
+ p.stdin.flush()
return p.wait() == 0
def realm_to_dn(self, realm):
return ','.join(['DC=%s' % part for part in realm.lower().split('.')])
def __well_known_container(self, container):
+ res = None
if container == 'system':
wkguiduc = 'AB1D30F3768811D1ADED00C04FD8D5CD'
elif container == 'computers':
@@ -43,51 +199,207 @@
wkguiduc = 'A361B2FFFFD211D1AA4B00C04FD7D83A'
elif container == 'users':
wkguiduc = 'A9D1CA15768811D1ADED00C04FD8D5CD'
- result = self.l.search_s('<WKGUID=%s,%s>' % (wkguiduc, self.realm_to_dn(self.realm)), ldap.SCOPE_SUBTREE, '(objectClass=container)', ['distinguishedName'])
+ result = ldap_search(self.l, '<WKGUID=%s,%s>' % (wkguiduc, self.realm_to_dn(self.realm)), ldap.SCOPE_SUBTREE, '(objectClass=container)', stringify_ldap(['distinguishedName']))
+ result = stringify_ldap(result)
if result and len(result) > 0 and len(result[0]) > 1 and 'distinguishedName' in result[0][1] and len(result[0][1]['distinguishedName']) > 0:
- return result[0][1]['distinguishedName'][-1]
+ res = result[0][1]['distinguishedName'][-1]
+
+ return stringify_ldap(res)
- def gpo_list(self):
- return self.l.search_s(self.__well_known_container('system'), ldap.SCOPE_SUBTREE, '(objectCategory=groupPolicyContainer)', [])
+ def user_from_sid(self, sid, attrs=[]):
+ res = ldap_search(self.l, self.__well_known_container('users'), ldap.SCOPE_SUBTREE, '(objectSID=%s)' % sid, stringify_ldap(attrs))
+ return res[0][1]
+
+ def get_domain_sid(self):
+ res = ldap_search(self.l, self.realm_to_dn(self.realm), ldap.SCOPE_BASE, "(objectClass=*)", [])
+ return ndr_unpack(security.dom_sid, res[0][1]["objectSid"][0])
+
+ def gpo_list(self, displayName=None, attrs=[]):
+ result = None
+ res = self.__well_known_container('system')
+ search_expr = '(objectClass=groupPolicyContainer)'
+ if displayName is not None:
+ search_expr = '(&(objectClass=groupPolicyContainer)(displayname=%s))' % ldb.binary_encode(displayName)
+ result = ldap_search(self.l, res, ldap.SCOPE_SUBTREE, search_expr, stringify_ldap(attrs))
+ result = stringify_ldap(result)
+ return result
def set_attr(self, dn, key, value):
- self.l.modify(dn, [(1, key, None), (0, key, value)])
+ ldap_modify(self.l, dn, stringify_ldap([(1, key, None), (0, key, value)]))
+
+ def create_gpo(self, displayName, container=None):
+ msg = self.gpo_list(displayName)
+ if len(msg) > 0:
+ print("A GPO already existing with name '%s'" % displayName)
+ return
- def create_gpo(self, displayName):
gpouuid = uuid.uuid4()
realm_dn = self.realm_to_dn(self.realm)
name = '{%s}' % str(gpouuid).upper()
dn = 'CN=%s,CN=Policies,CN=System,%s' % (name, realm_dn)
- ldap_mod = { 'displayName': [displayName], 'gPCFileSysPath': ['\\\\%s\\SysVol\\%s\\Policies\\%s' % (self.realm, self.realm, name)], 'objectClass': ['top', 'container', 'groupPolicyContainer'], 'gPCFunctionalityVersion': ['2'], 'flags': ['0'], 'versionNumber': ['0'] }
+ unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (self.realm, self.realm, name)
+ ldap_mod = { 'displayName': [displayName.encode('utf-8')], 'gPCFileSysPath': [unc_path.encode('utf-8')], 'objectClass': [b'groupPolicyContainer'], 'gPCFunctionalityVersion': [b'2'], 'flags': [b'0'], 'versionNumber': [b'0'] }
# gPCMachineExtensionNames MUST be assigned as gpos are modified (currently not doing this!)
machine_dn = 'CN=Machine,%s' % dn
user_dn = 'CN=User,%s' % dn
- sub_ldap_mod = { 'objectClass': ['top', 'container'] }
+ sub_ldap_mod = { 'objectClass': [b'container'] }
- gpo = GPOConnection(self.lp, self.creds, ldap_mod['gPCFileSysPath'][-1])
+ gpo = GPOConnection(self.lp, self.creds, unc_path)
try:
- self.l.add_s(dn, addlist(ldap_mod))
- self.l.add_s(machine_dn, addlist(sub_ldap_mod))
- self.l.add_s(user_dn, addlist(sub_ldap_mod))
+ ldap_add(self.l, dn, addlist(stringify_ldap(ldap_mod)))
+ ldap_add(self.l, machine_dn, addlist(stringify_ldap(sub_ldap_mod)))
+ ldap_add(self.l, user_dn, addlist(stringify_ldap(sub_ldap_mod)))
+ except LdapException as e:
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.add_s: %s\n' % e.info if e.info else e.msg)
+ gpo.initialize_empty_gpo(displayName)
+ if container:
+ self.set_link(dn, container)
+
+ def set_link(self, gpo_dn, container_dn, disabled=False, enforced=False):
+ gplink_options = 0
+ if disabled:
+ gplink_options |= (1 << 0)
+ if enforced:
+ gplink_options |= (1 << 1)
+
+ # Check if valid Container DN
+ msg = ldap_search(self.l,
+ container_dn, ldap.SCOPE_BASE,
+ "(objectClass=*)",
+ stringify_ldap(['gPLink']))[0][1]
+
+ # Update existing GPlinks or Add new one
+ existing_gplink = False
+ if 'gPLink' in msg:
+ gplist = parse_gplink(msg['gPLink'][0])
+ gplist = [gplist[k] for k in gplist]
+ existing_gplink = True
+ found = False
+ for g in gplist:
+ if g['dn'].lower() == gpo_dn.lower():
+ found = True
+ break
+ if found:
+ print("GPO '%s' already linked to this container" % gpo)
+ return
+ else:
+ gplist.insert(0, { 'dn' : gpo_dn, 'options' : gplink_options })
+ else:
+ gplist = []
+ gplist.append({ 'dn' : gpo_dn, 'options' : gplink_options })
+
+ gplink_str = encode_gplink(gplist)
- gpo.initialize_empty_gpo()
- # TODO: GPO links
+ if existing_gplink:
+ ldap_modify(self.l, container_dn, stringify_ldap([(1, 'gPLink', None), (0, 'gPLink', [gplink_str.encode('utf-8')])]))
+ else:
+ ldap_modify(self.l, container_dn, stringify_ldap([(0, 'gPLink', [gplink_str.encode('utf-8')])]))
+
+ def delete_link(self, gpo_dn, container_dn):
+ # Check if valid Container DN
+ msg = ldap_search(self.l,
+ container_dn, ldap.SCOPE_BASE,
+ "(objectClass=*)",
+ stringify_ldap(['gPLink']))[0][1]
+
+ found = False
+ if 'gPLink' in msg:
+ gplist = parse_gplink(msg['gPLink'][0])
+ gplist = [gplist[k] for k in gplist]
+ for g in gplist:
+ if g['dn'].lower() == gpo_dn.lower():
+ gplist.remove(g)
+ found = True
+ break
+ else:
+ raise Exception("No GPO(s) linked to this container")
+
+ if not found:
+ raise Exception("GPO '%s' not linked to this container" % gpo_dn)
+
+ if gplist:
+ gplink_str = encode_gplink(gplist)
+ ldap_modify(self.l, container_dn, stringify_ldap([(ldap.MOD_DELETE, 'gPLink', None), (ldap.MOD_ADD, 'gPLink', [gplink_str.encode('utf-8')])]))
+ else:
+ ldap_modify(self.l, container_dn, stringify_ldap([(ldap.MOD_DELETE, 'gPLink', None)]))
+
+ def delete_gpo(self, displayName):
+ msg = self.gpo_list(displayName)
+ if len(msg) == 0:
+ raise Exception("GPO '%s' does not exist" % displayName)
+
+ unc_path = msg[0][1]['gPCFileSysPath'][0]
+ gpo_dn = msg[0][1]['distinguishedName'][0]
+
+ # Remove links before deleting
+ linked_containers = self.get_gpo_containers(gpo_dn)
+ for container in linked_containers:
+ self.delete_link(gpo_dn, container['distinguishedName'][0].decode())
+
+ # Remove LDAP entries
+ ldap_delete(self.l, "CN=User,%s" % str(gpo_dn))
+ ldap_delete(self.l, "CN=Machine,%s" % str(gpo_dn))
+ ldap_delete(self.l, gpo_dn)
+ try:
+ # Remove GPO files
+ gpo = GPOConnection(self.lp, self.creds, unc_path)
+ gpo.cleanup_gpo()
except Exception as e:
- print str(e)
+ print(str(e))
+ traceback.print_exc(file=sys.stdout)
+
+ def get_gpo_containers(self, gpo):
+ '''lists dn of containers for a GPO'''
+
+ search_expr = "(&(objectClass=*)(gPLink=*%s*))" % gpo
+ msg = ldap_search(self.l, self.realm_to_dn(self.realm), ldap.SCOPE_SUBTREE, search_expr, [])
+ if not msg:
+ return []
+
+ return [res[1] for res in msg if type(res[1]) is dict]
+
+ def get_gpos_for_container(self, container_dn):
+ search_expr = '(distinguishedName=%s)' % container_dn
+ msg = ldap_search(self.l, self.realm_to_dn(self.realm), ldap.SCOPE_SUBTREE, search_expr, [])
+ if not msg:
+ return None
+
+ results = []
+ if 'gPLink' in msg[0][1]:
+ gpos = parse_gplink(msg[0][1]['gPLink'][-1])
+ else:
+ gpos = []
+ for gpo in gpos:
+ search_expr = '(distinguishedName=%s)' % gpos[gpo]['dn']
+ msg = ldap_search(self.l, self.realm_to_dn(self.realm), ldap.SCOPE_SUBTREE, search_expr, [])
+ results.append(msg[0])
+
+ return results
+
+ def get_containers_with_gpos(self):
+ search_expr = "(|(objectClass=organizationalUnit)(objectClass=domain))"
+ msg = ldap_search(self.l, self.realm_to_dn(self.realm), ldap.SCOPE_SUBTREE, search_expr, [])
+ if not msg:
+ return []
+
+ return [res[1] for res in msg if type(res[1]) is dict]
class GPOConnection(GPConnection):
def __init__(self, lp, creds, gpo_path):
GPConnection.__init__(self, lp, creds)
+ [dom_name, service, self.path] = parse_unc(gpo_path)
path_parts = [n for n in gpo_path.split('\\') if n]
- self.path_start = '\\\\' + '\\'.join(path_parts[:2])
- self.path = '\\'.join(path_parts[2:])
- self.name = path_parts[-1]
+ self.path_start = '\\\\' + '\\'.join([dom_name, service])
+ self.name = gpo_path.split('\\')[-1]
self.realm_dn = self.realm_to_dn(self.realm)
self.gpo_dn = 'CN=%s,CN=Policies,CN=System,%s' % (self.name, self.realm_dn)
try:
- self.conn = smb.SMB(path_parts[0], path_parts[1], lp=self.lp, creds=self.creds)
- except:
+ self.conn = smb.SMB(self.dc_hostname, service, lp=self.lp, creds=self.creds)
+ except Exception as e:
+ print ("Exception %s"%str(e))
+ traceback.print_exc(file=sys.stdout)
self.conn = None
def update_machine_gpe_ini(self, extension):
@@ -97,6 +409,8 @@
machine_extension_versions = ''
if ini_conf.has_option('General', 'MachineExtensionVersions'):
machine_extension_versions = ini_conf.get('General', 'MachineExtensionVersions').encode('ascii')
+ if type(machine_extension_versions) is bytes:
+ machine_extension_versions = machine_extension_versions.decode('utf-8')
itr = re.finditer('\[%s:\d+]' % extension, machine_extension_versions)
try:
new_ext_str = machine_extension_versions[:m.start()] + machine_extension_versions[m.end():]
@@ -109,11 +423,35 @@
ini_conf.set('General', 'MachineExtensionVersions', machine_extension_versions)
self.write('Group Policy\\GPE.INI', ini_conf)
- def initialize_empty_gpo(self):
+ def initialize_empty_gpo(self, displayName):
+ # Get new security descriptor
+ ds_sd_flags = ( security.SECINFO_OWNER |
+ security.SECINFO_GROUP |
+ security.SECINFO_DACL )
+ msg = self.gpo_list(displayName, attrs=stringify_ldap(['nTSecurityDescriptor']))
+ ds_sd_ndr = msg[0][1]['nTSecurityDescriptor'][0]
+ ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl()
+
+ # Create a file system security descriptor
+ domain_sid = self.get_domain_sid()
+ sddl = dsacl2fsacl(ds_sd, domain_sid)
+ fs_sd = security.descriptor.from_sddl(sddl, domain_sid)
+
self.__smb_mkdir_p('\\'.join([self.path, 'MACHINE']))
self.__smb_mkdir_p('\\'.join([self.path, 'USER']))
+
+ # Set ACL
+ sio = ( security.SECINFO_OWNER |
+ security.SECINFO_GROUP |
+ security.SECINFO_DACL |
+ security.SECINFO_PROTECTED_DACL )
+ self.conn.set_acl(self.path, fs_sd, sio)
+
self.__increment_gpt_ini()
+ def cleanup_gpo(self):
+ self.conn.deltree(self.path)
+
def __get_gpo_version(self, ini_conf=None):
if not ini_conf:
ini_conf = self.parse('GPT.INI')
@@ -137,7 +475,7 @@
if not ini_conf.has_section('General'):
ini_conf.add_section('General')
- ini_conf.set('General', 'Version', current)
+ ini_conf.set('General', 'Version', str(current))
self.write('GPT.INI', ini_conf)
self.set_attr(self.gpo_dn, 'versionNumber', current)
@@ -170,73 +508,77 @@
def __parse_dn(self, dn):
dn = dn % self.gpo_dn
- try:
- resp = self.l.search_s(dn, ldap.SCOPE_SUBTREE, '(objectCategory=packageRegistration)', [])
+ resp = ldap_search(self.l, dn, ldap.SCOPE_SUBTREE, '(objectCategory=packageRegistration)', [])
+ resp = stringify_ldap(resp)
+ if resp:
keys = ['objectClass', 'msiFileList', 'msiScriptPath', 'displayName', 'versionNumberHi', 'versionNumberLo']
results = {a[-1]['name'][-1]: {k: a[-1][k] for k in a[-1].keys() if k in keys} for a in resp}
- except Exception as e:
- if 'No such object' in str(e):
- results = {}
- else:
- raise
+ else:
+ results = {}
return results
def __mkdn_p(self, dn):
- attrs = { 'objectClass' : ['top', 'container'] }
+ attrs = { 'objectClass' : [b'top', b'container'] }
try:
- self.l.add_s(dn, addlist(attrs))
- except Exception as e:
- if e.args[-1]['desc'] == 'No such object':
+ ldap_add(self.l, dn, addlist(stringify_ldap(attrs)))
+ except LdapException as e:
+ if e.msg == 'No such object':
self.__mkdn_p(','.join(dn.split(',')[1:]))
- elif e.args[-1]['desc'] == 'Already exists':
+ elif e.msg == 'Already exists':
return
else:
- sys.stderr.write(e.args[-1]['info'])
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.add_s: %s\n' % e.info if e.info else e.msg)
try:
- self.l.add_s(dn, addlist(attrs))
- except Exception as e:
- if e.args[-1]['desc'] != 'Already exists':
- sys.stderr.write(e.args[-1]['info'])
+ ldap_add(self.l, dn, addlist(stringify_ldap(attrs)))
+ except LdapException as e:
+ if e.msg != 'Already exists':
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.add_s: %s\n' % e.info if e.info else e.msg)
def __write_dn(self, dn, ldap_config):
for cn in ldap_config.keys():
obj_dn = 'CN=%s,%s' % (cn, dn % self.gpo_dn)
if 'objectClass' not in ldap_config[cn]:
- ldap_config[cn]['objectClass'] = ['top', 'packageRegistration']
+ ldap_config[cn]['objectClass'] = [b'top', b'packageRegistration']
if 'msiFileList' not in ldap_config[cn]:
- ldap_config[cn]['msiFileList'] = os.path.splitext(ldap_config[cn]['msiScriptPath'][-1])[0] + '.zap'
+ ldap_config[cn]['msiFileList'] = [os.path.splitext(ldap_config[cn]['msiScriptPath'][-1])[0] + '.zap']
self.__mkdn_p(','.join(obj_dn.split(',')[1:]))
+ ldap_config[cn] = dict_to_bytes(ldap_config[cn])
try:
- self.l.add_s(obj_dn, addlist(ldap_config[cn]))
- except Exception as e:
- if e.args[-1]['desc'] == 'Already exists':
- try:
- self.l.modify_s(obj_dn, modlist({}, ldap_config[cn]))
- except Exception as e:
- sys.stderr.write(e.args[-1]['info'])
+ ldap_add(self.l, obj_dn, addlist(stringify_ldap(ldap_config[cn])))
+ except LdapException as e:
+ if e.msg == 'Already exists':
+ ldap_modify(self.l, obj_dn, modlist({}, stringify_ldap(ldap_config[cn])))
else:
- sys.stderr.write(e.args[-1]['info'])
+ traceback.print_exc(file=sys.stderr)
+ sys.stderr.write('ldap.add_s: %s\n' % e.info if e.info else e.msg)
- if os.path.splitext(ldap_config[cn]['msiFileList'][-1])[-1] == '.zap':
+ if os.path.splitext(ldap_config[cn]['msiFileList'][-1])[-1] == b'.zap':
inf_conf = self.__parse_inf(ldap_config[cn]['msiFileList'][-1])
if not inf_conf.has_section('Application'):
inf_conf.add_section('Application')
- inf_conf.set('Application', 'FriendlyName', ldap_config[cn]['displayName'][-1])
- inf_conf.set('Application', 'SetupCommand', 'rpm -i "%s"' % ldap_config[cn]['msiScriptPath'][-1])
- self.__write_inf(ldap_config[cn]['msiFileList'][-1], inf_conf)
+ inf_conf.set('Application', 'FriendlyName', ldap_config[cn]['displayName'][-1].decode('utf-8'))
+ inf_conf.set('Application', 'SetupCommand', 'rpm -i "%s"' % ldap_config[cn]['msiScriptPath'][-1].decode('utf-8'))
+ filename = ldap_config[cn]['msiFileList'][-1].split(self.path.encode('utf-8'))[-1]
+ self.__write_inf(filename, inf_conf)
def __parse_inf(self, filename):
inf_conf = ConfigParser()
if self.conn:
try:
policy = self.conn.loadfile('\\'.join([self.path, filename]))
- except:
+ except Exception as e:
+ sys.stderr.write(str(e))
policy = ''
inf_conf.optionxform=str
- try:
+ if PY3 and type(policy) is str:
inf_conf.readfp(StringIO(policy))
- except:
- inf_conf.readfp(StringIO(policy.decode('utf-16')))
+ else:
+ try:
+ inf_conf.readfp(StringIO(policy.decode('utf-8')))
+ except:
+ inf_conf.readfp(StringIO(policy.decode('utf-16')))
return inf_conf
def __parse_xml(self, filename):
@@ -254,31 +596,35 @@
try:
self.conn.mkdir(directory)
except Exception as e:
- if e[0] == -1073741766: # 0xC000003A: STATUS_OBJECT_PATH_NOT_FOUND
+ if e.args[0] == 0xC000003A: # STATUS_OBJECT_PATH_NOT_FOUND
self.__smb_mkdir_p(directory)
- elif e[0] == -1073741771: # 0xC0000035: STATUS_OBJECT_NAME_COLLISION
+ elif e.args[0] == 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
pass
else:
- print e[1]
+ print(e.args[1])
try:
self.conn.mkdir(path)
except Exception as e:
- if e[0] == -1073741771: # 0xC0000035: STATUS_OBJECT_NAME_COLLISION
+ if e.args[0] == 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
pass
else:
- print e[1]
+ print(e.args[1])
def __write(self, filename, text):
+ if type(filename) is bytes:
+ filename = filename.decode('utf-8')
path = '\\'.join([self.path, filename])
filedir = os.path.dirname((path).replace('\\', '/')).replace('/', '\\')
self.__smb_mkdir_p(filedir)
+ if PY3 and type(text) is str:
+ text = text.encode('utf-8')
try:
self.conn.savefile(path, text)
except Exception as e:
- if e[0] == -1073741766: # 0xC000003A: STATUS_OBJECT_PATH_NOT_FOUND
- print e[1] % (path)
+ if e.args[0] == 0xC000003A: # STATUS_OBJECT_PATH_NOT_FOUND
+ print(e.args[1] % (path))
else:
- print e[1]
+ print(e)
def __write_inf(self, filename, inf_config):
out = StringIO()
@@ -287,21 +633,22 @@
self.__write(filename, value)
def __write_xml(self, filename, xml_config):
- value = '<?xml version="1.0" encoding="utf-8"?>\r\n' + etree.tostring(xml_config, 'utf-8')
+ value = '<?xml version="1.0" encoding="utf-8"?>\r\n' + etree.tostring(xml_config, 'utf-8').decode('utf-8')
self.__write(filename, value)
def upload_file(self, local, remote_dir):
remote_path = '\\'.join([self.path, remote_dir])
self.__smb_mkdir_p(remote_path)
if os.path.exists(local):
- value = open(local).read()
+ value = open_bytes(local).read()
filename = '\\'.join([remote_path, os.path.basename(local)])
+ if PY3 and type(value) is str:
+ value = value.encode('utf-8')
try:
self.conn.savefile(filename, value)
except Exception as e:
- if e[0] == -1073741771: # 0xC0000035: STATUS_OBJECT_NAME_COLLISION
+ if e.args[0] == 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
sys.stderr.write('The file \'%s\' already exists at \'%s\' and could not be saved.' % (os.path.basename(local), remote_path))
else:
- sys.stderr.write(e[1])
+ sys.stderr.write(e.args[1])
return filename
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/defaults.py new/yast-gpmc-1.3.1/src/defaults.py
--- old/yast-gpmc-1.0/src/defaults.py 2017-11-17 16:11:00.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/defaults.py 2018-05-29 20:44:25.000000000 +0200
@@ -1,8 +1,11 @@
+from __future__ import absolute_import, division, print_function, unicode_literals
import xml.etree.ElementTree as etree
import uuid
import os.path
from subprocess import Popen, PIPE
+from yast import import_module
+import_module('UI')
from yast import UI
def select_script(title, policy, conn):
full_path = UI.AskForExistingFile('/', '*.sh *.py *.pl', title)
@@ -15,12 +18,12 @@
def query_rpm(filename):
out,_ = Popen(['rpm', '-qip', filename], stdout=PIPE, stderr=PIPE).communicate()
- return {line.split(':')[0].strip() : ':'.join(line.split(':')[1:]).strip() for line in out.strip().split('\n')}
+ return {line.split(b':')[0].strip() : b':'.join(line.split(b':')[1:]).strip() for line in out.strip().split(b'\n')}
def select_exec(title, policy, conn):
full_path = UI.AskForExistingFile('/', '*.rpm', title)
rpm_data = query_rpm(full_path)
- others = {'Name' : rpm_data['Name'], 'Version': rpm_data['Release']}
+ others = {'Name' : rpm_data[b'Name'], 'Version': rpm_data[b'Release']}
path = '%s\\%s' % (conn.path_start, conn.upload_file(full_path, 'MACHINE\\Applications'))
return (others, path)
@@ -373,6 +376,17 @@
'options' : None,
},
},
+ 'partial' : {
+ 'order' : 4,
+ 'title' : 'Parital',
+ 'get' : a.find('Properties').attrib['partial'] if a is not None and a.find('Properties') is not None and 'partial' in a.find('Properties').attrib.keys() else '',
+ 'set' : (lambda v : a.find('Properties').set('partial', v)),
+ 'valstr' : (lambda v : 'False' if v and int(v) == 0 else 'True'),
+ 'input' : {
+ 'type' : 'ComboBox',
+ 'options' : {'True' : '1', 'False' : '0'},
+ },
+ },
'value' : {
'order' : 2,
'title' : 'Value',
@@ -880,5 +894,5 @@
}
if __name__ == "__main__":
- print Policies
+ print(Policies)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/dialogs.py new/yast-gpmc-1.3.1/src/dialogs.py
--- old/yast-gpmc-1.0/src/dialogs.py 2017-11-17 16:11:09.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/dialogs.py 2018-05-29 20:44:25.000000000 +0200
@@ -1,7 +1,22 @@
+from __future__ import absolute_import, division, print_function, unicode_literals
from defaults import Policies, fetch_inf_value
-from complex import GPConnection, GPOConnection
+from complex import GPConnection, GPOConnection, dn_to_path, parse_gplink
+from yast import import_module
+import_module('Wizard')
+import_module('UI')
from yast import *
import re
+from functools import cmp_to_key
+from samba.dcerpc import security
+from samba.ndr import ndr_unpack
+import samba.security
+from samba.ntacls import dsacl2fsacl
+
+def have_x():
+ from subprocess import Popen, PIPE
+ p = Popen(['xset', '-q'], stdout=PIPE, stderr=PIPE)
+ return p.wait() == 0
+have_advanced_gui = have_x()
selected_gpo = None
@@ -10,17 +25,28 @@
global selected_gpo
self.conn = GPOConnection(lp, creds, selected_gpo[1]['gPCFileSysPath'][-1])
+ def __reset(self):
+ global have_advanced_gui
+ if not have_advanced_gui:
+ Wizard.RestoreNextButton()
+ Wizard.SetContentsButtons('Group Policy Management Editor', self.__gpme_page(), 'Group Policy Management Editor', '', 'Close')
+ if have_advanced_gui:
+ Wizard.HideNextButton()
+ else:
+ Wizard.HideAbortButton()
+ Wizard.HideBackButton()
+
def Show(self):
if not self.conn:
return Symbol('back')
- Wizard.SetContentsButtons('Group Policy Management Editor', self.__gpme_page(), 'Group Policy Management Editor', 'Back', 'Close')
- Wizard.DisableAbortButton()
+ self.__reset()
UI.SetFocus('gpme_tree')
policy = None
while True:
ret = UI.UserInput()
- if str(ret) in ['back', 'abort', 'next']:
+ if str(ret) in ['back', 'abort', 'next', 'cancel']:
+ ret = 'back'
break
elif str(ret) == 'gpme_tree':
policy = UI.QueryWidget('gpme_tree', 'CurrentItem')
@@ -72,7 +98,8 @@
def __change_values_prompt(self, values):
items = []
- for value in sorted(values.iteritems(), cmp=(lambda a,b : a[-1]['order']-b[-1]['order'])):
+ ckey = cmp_to_key(lambda a,b : a[-1]['order']-b[-1]['order'])
+ for value in sorted(values.items(), key=ckey):
k = value[0]
if not value[-1]['input']:
continue
@@ -127,7 +154,7 @@
header = Header(*header)
for key in opts:
values = sorted(opts[key]['values'].values(), key=(lambda x : x['order']))
- vals = tuple([k['valstr'](k['get']) for k in values])
+ vals = tuple([k['valstr'](k['get'].decode('utf-8')) if type(k['get']) is bytes else k['valstr'](k['get']) for k in values])
items.append(Item(Id(key), *vals))
buttons = []
if terms['add']:
@@ -224,35 +251,57 @@
class GPMC:
def __init__(self, lp, creds):
- global selected_gpo
- self.__get_creds(creds)
+ global selected_gpo, have_advanced_gui
self.realm = lp.get('realm')
self.lp = lp
self.creds = creds
- try:
- self.q = GPConnection(lp, creds)
- self.gpos = self.q.gpo_list()
- except:
- self.gpos = []
+ self.gpos = []
selected_gpo = None
+ self.__setup_menus()
+ if have_advanced_gui:
+ Wizard.HideAbortButton()
+ Wizard.HideBackButton()
+ Wizard.HideNextButton()
+ self.got_creds = self.__get_creds(creds)
+ while self.got_creds:
+ try:
+ self.q = GPConnection(lp, creds)
+ self.gpos = self.q.gpo_list()
+ self.realm_dn = self.q.realm_to_dn(self.realm)
+ break
+ except Exception as e:
+ print(str(e))
+ creds.set_password('')
+ self.got_creds = self.__get_creds(creds)
+
+ def __setup_menus(self):
+ UI.WizardCommand(Term('DeleteMenus'))
+ UI.WizardCommand(Term('AddMenu', '&File', 'file-menu'))
+ UI.WizardCommand(Term('AddMenuEntry', 'file-menu', 'Close', 'abort'))
def __get_creds(self, creds):
- if not creds.get_username() or not creds.get_password():
- UI.OpenDialog(self.__password_prompt(creds.get_username(), creds.get_password()))
+ if not creds.get_password():
+ UI.OpenDialog(self.__password_prompt(creds.get_username()))
while True:
subret = UI.UserInput()
if str(subret) == 'creds_ok':
user = UI.QueryWidget('username_prompt', 'Value')
password = UI.QueryWidget('password_prompt', 'Value')
+ UI.CloseDialog()
+ if not password:
+ return False
creds.set_username(user)
creds.set_password(password)
- if str(subret) == 'creds_cancel' or str(subret) == 'creds_ok':
+ return True
+ if str(subret) == 'creds_cancel':
UI.CloseDialog()
- break
+ return False
+ return True
- def __password_prompt(self, user, password):
+ def __password_prompt(self, user):
return MinWidth(30, VBox(
- Left(TextEntry(Id('username_prompt'), Opt('hstretch'), 'Username')),
+ Left(Label('To continue, type an administrator password')),
+ Left(TextEntry(Id('username_prompt'), Opt('hstretch'), 'Username', user)),
Left(Password(Id('password_prompt'), Opt('hstretch'), 'Password')),
Right(HBox(
PushButton(Id('creds_ok'), 'OK'),
@@ -260,69 +309,168 @@
))
))
- def __select_gpo(self, gpo_guid):
- global selected_gpo
- selected_gpo = None
+ def __find_gpo(self, gpo_guid):
+ fgpo = None
for gpo in self.gpos:
if gpo[1]['name'][-1] == gpo_guid:
- selected_gpo = gpo
+ fgpo = gpo
break
- return selected_gpo
+ return fgpo
+
+ def add_gpo(self, container=None):
+ UI.OpenDialog(self.__name_gpo())
+ sret = UI.UserInput()
+ if str(sret) == 'ok_name_gpo':
+ gpo_name = UI.QueryWidget('gpo_name_entry', 'Value')
+ self.q.create_gpo(gpo_name, container)
+ UI.CloseDialog()
+ try:
+ self.gpos = self.q.gpo_list()
+ except:
+ self.gpos = []
+
+ def del_gpo(self, displayName):
+ UI.OpenDialog(self.__request_delete_gpo())
+ sret = UI.UserInput()
+ if str(sret) == 'delete_gpo':
+ self.q.delete_gpo(displayName)
+ UI.CloseDialog()
+ try:
+ self.gpos = self.q.gpo_list()
+ except:
+ self.gpos = []
+
+ def del_link(self, child, parent):
+ UI.OpenDialog(self.__request_delete_link())
+ sret = UI.UserInput()
+ if str(sret) == 'delete_link':
+ self.q.delete_link(child, parent)
+ UI.CloseDialog()
+ try:
+ self.gpos = self.q.gpo_list()
+ except:
+ self.gpos = []
+
+ def __reset(self):
+ global have_advanced_gui
+ if not have_advanced_gui:
+ Wizard.RestoreBackButton()
+ Wizard.RestoreNextButton()
+ Wizard.RestoreAbortButton()
+ Wizard.SetContentsButtons('Group Policy Management Console', self.__gpmc_page(), self.__help(), 'Back', 'Edit GPO')
+ if have_advanced_gui:
+ Wizard.HideAbortButton()
+ Wizard.HideBackButton()
+ Wizard.HideNextButton()
+ else:
+ Wizard.DisableBackButton()
+ Wizard.DisableNextButton()
def Show(self):
global selected_gpo
- Wizard.SetContentsButtons('Group Policy Management Console', self.__gpmc_page(), self.__help(), 'Back', 'Edit GPO')
- Wizard.DisableBackButton()
- Wizard.DisableNextButton()
+ if not self.got_creds:
+ return Symbol('abort')
+ self.__reset()
UI.SetFocus('gpmc_tree')
current_page = 'Domains'
old_gpo_guid = None
gpo_guid = None
while True:
- ret = UI.UserInput()
+ event = UI.WaitForEvent()
+ if 'WidgetID' in event:
+ ret = event['WidgetID']
+ elif 'ID' in event:
+ ret = event['ID']
+ else:
+ raise Exception('ID not found in response %s' % str(event))
old_gpo_guid = gpo_guid
gpo_guid = UI.QueryWidget('gpmc_tree', 'CurrentItem')
- if str(ret) in ['back', 'abort']:
+ if str(ret) in ['back', 'abort', 'cancel']:
break
elif str(ret) == 'next':
break
elif str(ret) == 'add_gpo':
- UI.OpenDialog(self.__name_gpo())
- while True:
- sret = UI.UserInput()
- if str(sret) == 'ok_name_gpo':
- gpo_name = UI.QueryWidget('gpo_name_entry', 'Value')
- self.q.create_gpo(gpo_name)
- UI.CloseDialog()
- try:
- self.gpos = self.q.gpo_list()
- except:
- self.gpos = []
- Wizard.SetContentsButtons('Group Policy Management Console', self.__gpmc_page(), self.__help(), 'Back', 'Edit GPO')
- break
+ self.add_gpo()
+ self.__reset()
+ UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
+ current_page = 'Realm'
+ elif str(ret) == 'del_gpo':
+ self.del_gpo(UI.QueryWidget('link_order', 'CurrentItem'))
+ self.__reset()
+ UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
+ current_page = 'Realm'
+ elif ret == 'gpmc_tree' and event['EventReason'] == 'ContextMenuActivated':
+ parent = UI.QueryWidget('gpmc_tree', 'CurrentBranch')[-2]
+ if gpo_guid == 'Group Policy Objects':
+ UI.OpenContextMenu(self.__objs_context_menu())
+ elif gpo_guid != 'Domains' and self.__find_gpo(gpo_guid):
+ if parent != 'Group Policy Objects' and parent != self.realm_dn:
+ UI.OpenContextMenu(self.__gpo_context_menu(parent))
+ else:
+ UI.OpenContextMenu(self.__gpo_context_menu())
+ elif gpo_guid != 'Domains':
+ UI.OpenContextMenu(self.__objs_context_menu(gpo_guid))
+ elif ret == 'edit_gpo':
+ selected_gpo = self.__find_gpo(gpo_guid)
+ ret = 'next'
+ break
+ elif ret == 'context_del_gpo':
+ selected_gpo = self.__find_gpo(gpo_guid)
+ current_page = self.del_gpo(selected_gpo[1]['displayName'][-1])
+ self.__reset()
+ UI.ReplaceWidget('rightPane', Empty())
+ current_page = None
+ elif ret == 'context_del_link':
+ selected_gpo = self.__find_gpo(gpo_guid)
+ parent = UI.QueryWidget('gpmc_tree', 'CurrentBranch')[-2]
+ self.del_link(selected_gpo[1]['distinguishedName'][-1], parent)
+ self.__reset()
+ UI.ReplaceWidget('rightPane', Empty())
+ current_page = None
+ elif ret == 'context_add_gpo':
+ self.add_gpo()
+ self.__reset()
+ UI.ReplaceWidget('rightPane', Empty())
+ current_page = None
+ elif ret == 'context_add_gpo_and_link':
+ self.add_gpo(gpo_guid)
+ self.__reset()
+ UI.ReplaceWidget('rightPane', Empty())
+ current_page = None
elif UI.HasSpecialWidget('DumbTab'):
if gpo_guid == 'Domains':
if current_page != None:
Wizard.DisableNextButton()
UI.ReplaceWidget('rightPane', Empty())
current_page = None
- elif gpo_guid == self.realm:
+ elif gpo_guid == self.realm_dn:
if current_page != 'Realm':
Wizard.DisableNextButton()
- UI.ReplaceWidget('rightPane', self.__realm())
+ UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
current_page = 'Realm'
+ if ret == 'Linked Group Policy Objects':
+ UI.ReplaceWidget(Id('realm_tabContainer'), self.__container_links(gpo_guid))
+ elif ret == 'Delegation':
+ UI.ReplaceWidget(Id('realm_tabContainer'), self.__realm_delegation())
+ elif ret == 'Group Policy Inheritance':
+ UI.ReplaceWidget(Id('realm_tabContainer'), self.__realm_inheritance())
+ elif gpo_guid == 'Group Policy Objects':
+ if current_page != 'Group Policy Objects':
+ Wizard.DisableNextButton()
+ UI.ReplaceWidget('rightPane', Empty())
+ current_page = 'Group Policy Objects'
+ elif gpo_guid.lower().startswith('ou='):
+ UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
+ current_page = None
else:
- if str(ret) == 'advanced':
- self.__gpo_tab_adv(gpo_guid)
- continue
if current_page != 'Dumbtab' or old_gpo_guid != gpo_guid:
Wizard.EnableNextButton()
- selected_gpo = self.__select_gpo(gpo_guid)
+ selected_gpo = self.__find_gpo(gpo_guid)
UI.ReplaceWidget('rightPane', self.__gpo_tab(gpo_guid))
current_page = 'Dumbtab'
if str(ret) == 'Scope':
- UI.ReplaceWidget('gpo_tabContents', self.__scope_page())
+ UI.ReplaceWidget('gpo_tabContents', self.__scope_page(gpo_guid))
elif str(ret) == 'Details':
UI.ReplaceWidget('gpo_tabContents', self.__details_page(gpo_guid))
elif str(ret) == 'Settings':
@@ -342,6 +490,26 @@
return Symbol(ret)
+ def __gpo_context_menu(self, parent=None):
+ if parent:
+ delete_id = 'context_del_link'
+ else:
+ delete_id = 'context_del_gpo'
+ return Term('menu', [
+ Item(Id('edit_gpo'), 'Edit...'),
+ Item(Id(delete_id), 'Delete')
+ ])
+
+ def __objs_context_menu(self, container=None):
+ if container:
+ return Term('menu', [
+ Item(Id('context_add_gpo_and_link'), 'Create a GPO in this domain, and Link it here...')
+ ])
+ else:
+ return Term('menu', [
+ Item(Id('context_add_gpo'), 'New')
+ ])
+
def __name_gpo(self):
return MinWidth(30, VBox(
TextEntry(Id('gpo_name_entry'), Opt('hstretch'), 'GPO Name'),
@@ -351,13 +519,47 @@
))
))
+ def __request_delete_gpo(self):
+ return MinWidth(30, VBox(
+ Label('Do you want to delete this GPO and all links to it in this\ndomain? This will not delete links in other domains.'),
+ Right(HBox(
+ PushButton(Id('delete_gpo'), 'Yes'),
+ PushButton(Id('cancel_delete_gpo'), 'No'),
+ ))
+ ))
+
+ def __request_delete_link(self):
+ return MinWidth(30, VBox(
+ Label('Do you want to delete this link?\nThis will not delete the GPO itself.'),
+ Right(HBox(
+ PushButton(Id('delete_link'), 'OK'),
+ PushButton(Id('cancel_delete_link'), 'Cancel'),
+ ))
+ ))
+
def __help(self):
return 'Group Policy Management Console'
- def __scope_page(self):
- return RichText('Contents of the scope page')
+ def __scope_page(self, gpo_guid):
+ header = Header('Location', 'Enforced', 'Link Enabled', 'Path')
+ contents = []
+ links = self.q.get_gpo_containers(gpo_guid)
+ for link in links:
+ if b'domain' in link['objectClass']:
+ name = self.realm.lower()
+ else:
+ name = link['name'][-1]
+ gplist = parse_gplink(link['gPLink'][-1])[gpo_guid]
+ vals = Item(name, str(gplist['enforced']), str(gplist['enabled']), dn_to_path(self.realm.lower(), link['distinguishedName'][-1]))
+ contents.append(vals)
+ return VBox(
+ Left(Label('Links')),
+ Table(Id('scope_links'), header, contents)
+ )
def __ms_time_to_readable(self, timestamp):
+ if type(timestamp) is bytes:
+ timestamp = timestamp.decode()
m = re.match('(?P<year>\d\d\d\d)(?P<month>\d\d)(?P<day>\d\d)(?P<hour>\d\d)(?P<minute>\d\d)(?P<second>\d\d)\..*', timestamp)
if m:
return '%s/%s/%s %s:%s:%s UTC' % (m.group('month'), m.group('day'), m.group('year'), m.group('hour'), m.group('minute'), m.group('second'))
@@ -375,6 +577,16 @@
status_selection[0] = True
combo_options = [Item('All settings disabled', status_selection[0]), Item('Computer configuration settings disabled', status_selection[1]), Item('Enabled', status_selection[2]), Item('User configuration settings disabled', status_selection[3])]
+
+ msg = self.q.gpo_list(selected_gpo[1]['displayName'][-1], attrs=['nTSecurityDescriptor'])
+ if msg:
+ ds_sd_ndr = msg[0][1]['nTSecurityDescriptor'][0]
+ ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr)
+ owner_obj = self.q.user_from_sid(ds_sd.owner_sid)
+ owner = owner_obj['sAMAccountName'][-1].decode('utf-8')
+ else:
+ owner = 'Unknown'
+
return Top(
HBox(
HWeight(1, VBox(
@@ -389,7 +601,7 @@
)),
HWeight(2, VBox(
Left(Label(self.realm)), VSpacing(),
- Left(Label('Unknown')), VSpacing(),
+ Left(Label(owner)), VSpacing(),
Left(Label(self.__ms_time_to_readable(selected_gpo[1]['whenCreated'][-1]))), VSpacing(),
Left(Label(self.__ms_time_to_readable(selected_gpo[1]['whenChanged'][-1]))), VSpacing(),
Left(Label('%d' % (int(selected_gpo[1]['versionNumber'][-1]) >> 16))), VSpacing(),
@@ -401,30 +613,74 @@
)
def __settings_page(self):
- return RichText('Contents of the settings page')
+ return Top(HBox(Empty()))
def __delegation_page(self):
- return RichText('Contents of the delegation page')
+ return Top(HBox(Empty()))
def __forest(self):
+ gp_containers = self.q.get_containers_with_gpos()
items = []
for gpo in self.gpos:
items.append(Item(Id(gpo[1]['name'][-1]), gpo[1]['displayName'][-1]))
- forest = [Item('Domains', True, [Item(self.realm, True, items)])]
- contents = Tree(Id('gpmc_tree'), Opt('notify'), 'Group Policy Management', forest)
+ folders = []
+ for container in gp_containers:
+ if b'domain' in container['objectClass']:
+ gplists = parse_gplink(container['gPLink'][-1])
+ for gpname in gplists:
+ gpo = self.__find_gpo(gpname)
+ displayName = gpo[1]['displayName'][-1] if gpo else gpname
+ folders.append(Item(Id(gpname), displayName))
+ else:
+ container_objs = []
+ if 'gPLink' in container:
+ gplists = parse_gplink(container['gPLink'][-1])
+ else:
+ gplists = []
+ for gpname in gplists:
+ gpo = self.__find_gpo(gpname)
+ displayName = gpo[1]['displayName'][-1] if gpo else gpname
+ container_objs.append(Item(Id(gpname), displayName))
+ folders.append(Item(Id(container['distinguishedName'][-1]), container['name'][-1], False, container_objs))
+ folders.append(Item('Group Policy Objects', False, items))
+ forest = [
+ Item('Domains', True,
+ [
+ Item(Id(self.realm_dn), self.realm, True, folders)
+ ])
+ ]
+ contents = Tree(Id('gpmc_tree'), Opt('notify', 'immediate', 'notifyContextMenu'), 'Group Policy Management', forest)
return contents
- def __realm(self):
+ def __container(self, dn):
+ global have_advanced_gui
+ if have_advanced_gui:
+ buttons = Empty()
+ else:
+ buttons = Right(HBox(
+ PushButton(Id('del_gpo'), 'Delete GPO'),
+ PushButton(Id('add_gpo'), 'Create a GPO')
+ ))
return VBox(
- Frame(self.realm, DumbTab(['Linked Group Policy Objects', 'Group Policy Inheritance', 'Delegation'], ReplacePoint(Id('realm_tabContainer'), self.__realm_links()))),
- Right(HBox(PushButton(Id('add_gpo'), 'Create a GPO'))),
+ Frame(self.realm, DumbTab([
+ 'Linked Group Policy Objects',
+ #'Group Policy Inheritance',
+ #'Delegation'
+ ], ReplacePoint(Id('realm_tabContainer'), self.__container_links(dn)))),
+ buttons,
)
- def __realm_links(self):
+ def __realm_delegation(self):
+ return Top(HBox(Empty()))
+
+ def __realm_inheritance(self):
+ return Top(HBox(Empty()))
+
+ def __container_links(self, dn):
header = Header('Link Order', 'GPO', 'Enforced', 'Link Enabled', 'GPO Status', 'WMI Filter', 'Modified', 'Domain')
contents = []
- for gpo in self.gpos:
+ for gpo in self.q.get_gpos_for_container(dn):
status = ''
if gpo[1]['flags'][-1] == '0':
status = 'Enabled'
@@ -441,11 +697,15 @@
def __gpo_tab(self, gpo_guid):
global selected_gpo
+ if not selected_gpo:
+ return Top(HBox(Empty()))
gpo_name = selected_gpo[1]['displayName'][-1]
- return Frame(gpo_name, ReplacePoint(Id('gpo_tabContainer'), VBox(self.__details_page(gpo_guid), Right(PushButton(Id('advanced'), 'Advanced')))))
-
- def __gpo_tab_adv(self, gpo_guid):
- UI.ReplaceWidget('gpo_tabContainer', DumbTab(Id('gpo_tab'), ['Scope', 'Details', 'Settings', 'Delegation'], ReplacePoint(Id('gpo_tabContents'), self.__scope_page())))
+ return Frame(gpo_name, DumbTab(Id('gpo_tab'), [
+ 'Scope',
+ Item('Details', True),
+ #'Settings',
+ #'Delegation'
+ ], ReplacePoint(Id('gpo_tabContents'), self.__details_page(gpo_guid))))
def __gpmc_page(self):
return HBox(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/gpmc.desktop.in new/yast-gpmc-1.3.1/src/gpmc.desktop.in
--- old/yast-gpmc-1.0/src/gpmc.desktop.in 2017-11-17 16:16:59.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/gpmc.desktop.in 2018-05-29 20:44:25.000000000 +0200
@@ -16,7 +16,7 @@
X-SuSE-YaST-AutoInstResource=gpmc
Icon=yast-gpmc
-Exec="/usr/bin/xdg-su -c '@CLIENTDIR@/gpmc.py'"
+Exec=yast2 '@CLIENTDIR@/gpmc.py'
Name=Group Policy Management Console
GenericName=Manage Group Policy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/gpmc.py new/yast-gpmc-1.3.1/src/gpmc.py
--- old/yast-gpmc-1.0/src/gpmc.py 2017-11-17 16:11:18.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/gpmc.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,56 +0,0 @@
-import sys, os, traceback
-import optparse
-
-from samba.param import LoadParm
-from samba.credentials import Credentials
-
-from subprocess import Popen, PIPE
-
-sys.path.append(sys.path[0]+"/../include/gpmc")
-
-from wizards import GPMCSequence
-
-if __name__ == "__main__":
- parser = optparse.OptionParser('gpmc [options]')
-
- # Yast command line args
- yast_opt = optparse.OptionGroup(parser, 'Command line options for the YaST2 Qt UI')
- yast_opt.add_option('--nothreads', help='run without additional UI threads', action='store_true')
- yast_opt.add_option('--fullscreen', help='use full screen for `opt(`defaultsize) dialogs', action='store_true')
- yast_opt.add_option('--noborder', help='no window manager border for `opt(`defaultsize) dialogs', action='store_true')
- yast_opt.add_option('--auto-fonts', help='automatically pick fonts, disregard Qt standard settings', action='store_true')
- yast_opt.add_option('--macro', help='play a macro right on startup')
- parser.add_option_group(yast_opt)
-
- # Get the command line options
- parser.add_option('--ncurses', dest='ncurses', help='Whether to run yast via ncurses interface', action='store_true')
- credopts = optparse.OptionGroup(parser, 'Credentials Options')
- credopts.add_option('--password', dest='password', help='Password')
- credopts.add_option('-U', '--username', dest='username', help='Username')
- credopts.add_option('--krb5-ccache', dest='krb5_ccache', help='Kerberos Credentials cache')
- parser.add_option_group(credopts)
-
- # Set the options and the arguments
- (opts, args) = parser.parse_args()
-
- # Set the loadparm context
- lp = LoadParm()
- if os.getenv("SMB_CONF_PATH") is not None:
- lp.load(os.getenv("SMB_CONF_PATH"))
- else:
- lp.load_default()
-
- # Initialize the session
- creds = Credentials()
- if opts.username and opts.password:
- creds.set_username(opts.username)
- creds.set_password(opts.password)
- elif opts.krb5_ccache:
- creds.set_named_ccache(opts.krb5_ccache)
- creds.guess(lp)
-
- try:
- GPMCSequence(lp, creds)
- except:
- traceback.print_exc(file=sys.stdout)
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/gpmc.py.in new/yast-gpmc-1.3.1/src/gpmc.py.in
--- old/yast-gpmc-1.0/src/gpmc.py.in 1970-01-01 01:00:00.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/gpmc.py.in 2018-05-29 20:44:25.000000000 +0200
@@ -0,0 +1,60 @@
+from __future__ import absolute_import, division, print_function, unicode_literals
+import sys, os, traceback
+import optparse
+
+from samba.param import LoadParm
+from samba.credentials import Credentials
+
+from subprocess import Popen, PIPE
+
+sys.path.append('@INCLUDEDIR@')
+
+from wizards import GPMCSequence
+
+if __name__ == "__main__":
+ parser = optparse.OptionParser('gpmc [options]')
+
+ # Yast command line args
+ yast_opt = optparse.OptionGroup(parser, 'Command line options for the YaST2 Qt UI')
+ yast_opt.add_option('--nothreads', help='run without additional UI threads', action='store_true')
+ yast_opt.add_option('--fullscreen', help='use full screen for `opt(`defaultsize) dialogs', action='store_true')
+ yast_opt.add_option('--noborder', help='no window manager border for `opt(`defaultsize) dialogs', action='store_true')
+ yast_opt.add_option('--auto-fonts', help='automatically pick fonts, disregard Qt standard settings', action='store_true')
+ yast_opt.add_option('--macro', help='play a macro right on startup')
+ parser.add_option_group(yast_opt)
+
+ # Get the command line options
+ parser.add_option('--ncurses', dest='ncurses', help='Whether to run yast via ncurses interface', action='store_true')
+ credopts = optparse.OptionGroup(parser, 'Credentials Options')
+ credopts.add_option('--password', dest='password', help='Password')
+ credopts.add_option('-U', '--username', dest='username', help='Username')
+ credopts.add_option('--krb5-ccache', dest='krb5_ccache', help='Kerberos Credentials cache')
+ parser.add_option_group(credopts)
+
+ # Set the options and the arguments
+ (opts, args) = parser.parse_args()
+
+ # Set the loadparm context
+ lp = LoadParm()
+ if os.getenv("SMB_CONF_PATH") is not None:
+ lp.load(os.getenv("SMB_CONF_PATH"))
+ else:
+ try:
+ lp.load_default()
+ except RuntimeError:
+ pass
+
+ # Initialize the session
+ creds = Credentials()
+ if opts.username and opts.password:
+ creds.set_username(opts.username)
+ creds.set_password(opts.password)
+ elif opts.krb5_ccache:
+ creds.set_named_ccache(opts.krb5_ccache)
+ creds.guess(lp)
+
+ try:
+ GPMCSequence(lp, creds)
+ except:
+ traceback.print_exc(file=sys.stdout)
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/src/wizards.py new/yast-gpmc-1.3.1/src/wizards.py
--- old/yast-gpmc-1.0/src/wizards.py 2017-11-17 16:11:27.000000000 +0100
+++ new/yast-gpmc-1.3.1/src/wizards.py 2018-05-29 20:44:25.000000000 +0200
@@ -1,4 +1,9 @@
+from __future__ import absolute_import, division, print_function, unicode_literals
from dialogs import GPMC, GPME
+from yast import import_module
+import_module('Wizard')
+import_module('UI')
+import_module('Sequencer')
from yast import Wizard, UI, Sequencer, Code, Symbol
def GPMCSequence(lp, creds):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast-gpmc-1.0/yast2-gpmc.spec.in new/yast-gpmc-1.3.1/yast2-gpmc.spec.in
--- old/yast-gpmc-1.0/yast2-gpmc.spec.in 2017-11-08 19:20:04.000000000 +0100
+++ new/yast-gpmc-1.3.1/yast2-gpmc.spec.in 1970-01-01 01:00:00.000000000 +0100
@@ -1,31 +0,0 @@
-@HEADER-COMMENT@
-
-@HEADER@
-Requires: yast2
-BuildRequires: perl-XML-Writer update-desktop-files yast2 yast2-devtools yast2-testsuite
-
-BuildArchitectures: noarch
-
-Summary: Configuration of gpmc
-
-%description
--
-
-@PREP@
-
-@BUILD@
-
-@INSTALL@
-
-@CLEAN@
-
-%files
-%defattr(-,root,root)
-%dir @yncludedir@/gpmc
-@yncludedir@/gpmc/*
-@clientdir@/gpmc.ycp
-@clientdir@/gpmc_*.ycp
-@moduledir@/Gpmc.*
-@moduledir@/Gpmc2.*
-@desktopdir@/gpmc.desktop
-%doc @docdir@
1
0
Hello community,
here is the log from the commit of package uhd for openSUSE:Factory checked in at 2018-05-30 12:23:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/uhd (Old)
and /work/SRC/openSUSE:Factory/.uhd.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "uhd"
Wed May 30 12:23:42 2018 rev:23 rq:612905 version:3.9.7
Changes:
--------
--- /work/SRC/openSUSE:Factory/uhd/uhd.changes 2018-01-17 21:59:17.112474767 +0100
+++ /work/SRC/openSUSE:Factory/.uhd.new/uhd.changes 2018-05-30 12:41:42.731582036 +0200
@@ -1,0 +2,8 @@
+Tue May 29 11:03:42 UTC 2018 - adam.majer(a)suse.de
+
+- fixed build with Boost 1.67 (bsc#1089820)
+ uhd-fix-for-boost-1_67.patch
+- drop _constraints and use memory-constraints package instead.
+- re-enabled package tests
+
+-------------------------------------------------------------------
Old:
----
_constraints
New:
----
uhd-fix-for-boost-1_67.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ uhd.spec ++++++
--- /var/tmp/diff_new_pack.7sJjyF/_old 2018-05-30 12:41:44.451521948 +0200
+++ /var/tmp/diff_new_pack.7sJjyF/_new 2018-05-30 12:41:44.455521809 +0200
@@ -23,7 +23,7 @@
%define src_ver 003.009.007
%define img_ver 003.009.007
Summary: The driver for USRP SDR boards
-License: GPL-3.0+
+License: GPL-3.0-or-later
Group: Hardware/Other
Url: http://ettus-apps.sourcerepo.com/redmine/ettus/projects/uhd/wiki
Source0: http://files.ettus.com/binaries/uhd_stable/uhd_%{src_ver}-release/uhd_%{ver…
@@ -32,6 +32,7 @@
Patch0: fix-for-armv6l-armv7l-build-failure.patch
# PATCH-FIX-OPENSUSE uhd-fix-for-boost-1_66.patch
Patch1: uhd-fix-for-boost-1_66.patch
+Patch2: uhd-fix-for-boost-1_67.patch
%if 0%{?suse_version} > 1325
BuildRequires: libboost_filesystem-devel
BuildRequires: libboost_program_options-devel
@@ -50,6 +51,7 @@
BuildRequires: fdupes
BuildRequires: gcc-c++
BuildRequires: gpsd-devel
+BuildRequires: memory-constraints
BuildRequires: orc
BuildRequires: pkg-config
BuildRequires: python-Mako >= 0.4
@@ -138,21 +140,21 @@
%setup -q -n %{name}_%{version}-release
%patch0 -p1
%patch1 -p1
+%patch2 -p1
# remove buildtime from documentation
echo "HTML_TIMESTAMP = NO" >> docs/Doxyfile.in
%build
touch ../README.md
+%limit_build
%cmake \
-DPYTHON_EXECUTABLE=/usr/bin/python2 \
-DENABLE_GPSD=1
-make VERBOSE=1 %{?_smp_mflags}
+%make_jobs
%check
-# Disable tests due to failure of convert_test on openSUSE 13.1
-#cd build
-#make VERBOSE=1 test
+%ctest
%install
%cmake_install
++++++ uhd-fix-for-boost-1_67.patch ++++++
Index: uhd_3.9.7-release/lib/usrp/x300/x300_impl.cpp
===================================================================
--- uhd_3.9.7-release.orig/lib/usrp/x300/x300_impl.cpp
+++ uhd_3.9.7-release/lib/usrp/x300/x300_impl.cpp
@@ -1486,7 +1486,7 @@ void x300_impl::sync_times(mboard_member
bool x300_impl::wait_for_clk_locked(mboard_members_t& mb, boost::uint32_t which, double timeout)
{
- boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(timeout * 1000.0);
+ boost::system_time timeout_time = boost::get_system_time() + boost::posix_time::milliseconds(static_cast<long>(timeout * 1000));
do {
if (mb.fw_regmap->clock_status_reg.read(which)==1)
return true;
Index: uhd_3.9.7-release/examples/benchmark_rate.cpp
===================================================================
--- uhd_3.9.7-release.orig/examples/benchmark_rate.cpp
+++ uhd_3.9.7-release/examples/benchmark_rate.cpp
@@ -364,7 +364,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]
if(ref != "internal") {
std::cout << "Now confirming lock on clock signals..." << std::endl;
bool is_locked = false;
- boost::system_time end_time = boost::get_system_time() + boost::posix_time::milliseconds(CLOCK_TIMEOUT);
+ boost::system_time end_time = boost::get_system_time() + boost::posix_time::microseconds(static_cast<long>(1000*CLOCK_TIMEOUT));
for (int i = 0; i < num_mboards; i++) {
if (ref == "mimo" and i == 0) continue;
while((is_locked = usrp->get_mboard_sensor("ref_locked",i).to_bool()) == false and
@@ -471,7 +471,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]
const long usecs = long((duration - secs)*1e6);
boost::this_thread::sleep(boost::posix_time::seconds(secs)
+ boost::posix_time::microseconds(usecs)
- + boost::posix_time::milliseconds( (rx_channel_nums.size() <= 1 and tx_channel_nums.size() <= 1) ? 0 : (INIT_DELAY * 1000))
+ + boost::posix_time::milliseconds( (rx_channel_nums.size() <= 1 and tx_channel_nums.size() <= 1) ? 0 : static_cast<long>((INIT_DELAY * 1000)))
);
//interrupt and join the threads
Index: uhd_3.9.7-release/examples/tx_samples_from_file.cpp
===================================================================
--- uhd_3.9.7-release.orig/examples/tx_samples_from_file.cpp
+++ uhd_3.9.7-release/examples/tx_samples_from_file.cpp
@@ -199,7 +199,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]
else if (type == "short") send_from_file<std::complex<short> >(tx_stream, file, spb);
else throw std::runtime_error("Unknown type " + type);
- if(repeat and delay != 0.0) boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
+ if(repeat and delay != 0.0) boost::this_thread::sleep(boost::posix_time::microseconds(static_cast<long>(1000*delay)));
} while(repeat and not stop_signal_called);
//finished
Index: uhd_3.9.7-release/examples/rx_samples_to_file.cpp
===================================================================
--- uhd_3.9.7-release.orig/examples/rx_samples_to_file.cpp
+++ uhd_3.9.7-release/examples/rx_samples_to_file.cpp
@@ -182,7 +182,7 @@ bool check_locked_sensor(std::vector<std
while (true) {
if ((not first_lock_time.is_not_a_date_time()) and
- (boost::get_system_time() > (first_lock_time + boost::posix_time::seconds(setup_time))))
+ (boost::get_system_time() > (first_lock_time + boost::posix_time::milliseconds(static_cast<long>(1000*setup_time)))))
{
std::cout << " locked." << std::endl;
break;
@@ -196,7 +196,7 @@ bool check_locked_sensor(std::vector<std
else {
first_lock_time = boost::system_time(); //reset to 'not a date time'
- if (boost::get_system_time() > (start + boost::posix_time::seconds(setup_time))){
+ if (boost::get_system_time() > (start + boost::posix_time::milliseconds(static_cast<long>(setup_time)))){
std::cout << std::endl;
throw std::runtime_error(str(boost::format("timed out waiting for consecutive locks on sensor \"%s\"") % sensor_name));
}
@@ -317,7 +317,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]
//set the antenna
if (vm.count("ant")) usrp->set_rx_antenna(ant);
- boost::this_thread::sleep(boost::posix_time::seconds(setup_time)); //allow for some setup time
+ boost::this_thread::sleep(boost::posix_time::milliseconds(static_cast<long>(1000*setup_time))); //allow for some setup time
//check Ref and LO Lock detect
if (not vm.count("skip-lo")){
1
0
Hello community,
here is the log from the commit of package texmath for openSUSE:Factory checked in at 2018-05-30 11:55:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/texmath (Old)
and /work/SRC/openSUSE:Factory/.texmath.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "texmath"
Wed May 30 11:55:06 2018 rev:24 rq:607965 version:0.11
Changes:
--------
--- /work/SRC/openSUSE:Factory/texmath/texmath.changes 2017-09-15 22:30:23.207279590 +0200
+++ /work/SRC/openSUSE:Factory/.texmath.new/texmath.changes 2018-05-30 12:41:17.252468334 +0200
@@ -1,0 +2,67 @@
+Mon May 14 17:02:11 UTC 2018 - psimons(a)suse.com
+
+- Update texmath to version 0.11.
+
+ * Changed treatment of non-ASCII characters.
+ Previously we ensured that the output of conversion to tex
+ was pure ASCII. This meant rendering "ä" as "a", for
+ example, and it meant that many characters (e.g. Chinese)
+ simply got replaced with an empty string, while others
+ got replaced with "[?]".
+
+ This was not a particularly helpful behavior. Including
+ the unicode characters verbatim doesn't interfere with
+ latex compilation. They often won't show up in the generated
+ math, but that is no worse than what happened before.
+
+ This change passes through unicode characters unchanged
+ when they can't be converted to standard LaTeX commands.
+
+ An important reason for including the unicode characters
+ is that pandoc uses TeX to represent math in its AST.
+ So, for example, if you convert HTML with mathml to docx,
+ you'll currently lose all Chinese characters, since they'll
+ disappear in the TeX intermediary, even though a direct
+ mathml to ooml conversion would have passed them through.
+ With this change, these conversions will work better
+ (see jgm/pandoc#4642).
+
+ + Removed Text.TeXMath.Unicode.ToASCII (API change).
+ + Removed cbits that were needed for that module.
+ + Modified Tex.TeXMath.Unicode.ToTeX to pass through
+ unicode characters that can't be converted, rather
+ than trying to asciify them or remove them.
+
+ * Render degree symbol in tex as `{^\circ}`.
+ * eqn writer: use uppercase letters in unicode escapes (jgm/pandoc#4597).
+ * Handle multicharacter operators better in Eqn, TeX, OMML (#109).
+ * OMML reader: unwrap `<w:...>` tags immediately under `<m:oMath>`
+ (#111, Jesse Rosenthal).
+ * Expose Text.TeXMath.TeX (TeX rendering functions) (#108).
+ This is needed in order to use getTeXMath from Text.TeXMath.Unicode.ToTeX.
+ * Pandoc writer: don't insert punctuation space before explicit space
+ (#107). E.g. in `2,\!4`.
+ * Fix end-line command ('\\') in AMSmath environments (ARATA Mizuki).
+ The end-line command in AMSmath environments does not allow spaces
+ before its optional argument.
+ * Use `\in` for SMALL ELEMENT OF in "base" (Vaclav Haisman).
+ * Use `\ni` in base for U+220D (#103).
+ * Improved unicode -> tex symbol lookup. Previously we had many
+ cases where the lookup table would map a unicode character to
+ the empty string for the base package, and this would print finding
+ a good match in another package in the environment.
+ * Added support for `\symbf` (#101).
+ * Revert "migrating the lookup structures for Unicode/ToTex.hs to
+ use C source files to accelerate builds." This change gave us somewhat
+ faster builds (using less memory), but at a huge cost of
+ maintainability.
+ * Removed AlignDefault from Alignment (API change, #102).
+ AlignDefault doesn't make sense for a converter between
+ formats that may have different defaults. We now properly treat
+ centering as the default in MathML and OMML input.
+ * Update tests that should have been updated for 0.9.4.3.
+ * MathML writer: put linethickness attribute directly on mfrac
+ element. This fixes binomial rendering.
+ * Pandoc writer: better handle accented characters (jgm/pandoc#3922).
+
+-------------------------------------------------------------------
Old:
----
texmath-0.9.4.1.tar.gz
New:
----
texmath-0.11.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ texmath.spec ++++++
--- /var/tmp/diff_new_pack.6prp4e/_old 2018-05-30 12:41:17.764450597 +0200
+++ /var/tmp/diff_new_pack.6prp4e/_new 2018-05-30 12:41:17.768450458 +0200
@@ -1,7 +1,7 @@
#
# spec file for package texmath
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,10 +19,10 @@
%global pkg_name texmath
%bcond_with tests
Name: %{pkg_name}
-Version: 0.9.4.1
+Version: 0.11
Release: 0
Summary: Conversion between formats used to represent mathematics
-License: GPL-2.0
+License: GPL-2.0-or-later
Group: Development/Libraries/Haskell
URL: https://hackage.haskell.org/package/%{name}
Source0: https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.t…
@@ -111,12 +111,12 @@
%ghc_pkg_recache
%files
-%doc LICENSE
+%license LICENSE
%doc README.markdown changelog
%{_bindir}/%{name}
%files -n ghc-%{name} -f ghc-%{name}.files
-%doc LICENSE
+%license LICENSE
%files -n ghc-%{name}-devel -f ghc-%{name}-devel.files
%doc README.markdown changelog
++++++ texmath-0.9.4.1.tar.gz -> texmath-0.11.tar.gz ++++++
++++ 134678 lines of diff (skipped)
1
0
Hello community,
here is the log from the commit of package sysvinit for openSUSE:Factory checked in at 2018-05-30 11:41:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sysvinit (Old)
and /work/SRC/openSUSE:Factory/.sysvinit.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sysvinit"
Wed May 30 11:41:12 2018 rev:165 rq:612627 version:2.88+
Changes:
--------
--- /work/SRC/openSUSE:Factory/sysvinit/powerd.changes 2016-01-20 09:54:08.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.sysvinit.new/powerd.changes 2018-05-30 12:41:04.944893823 +0200
@@ -1,0 +2,5 @@
+Thu May 24 10:30:13 CEST 2018 - kukuk(a)suse.de
+
+- Use %license instead of %doc [bsc#1082318]
+
+-------------------------------------------------------------------
--- /work/SRC/openSUSE:Factory/sysvinit/sysvinit.changes 2016-10-14 09:26:48.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.sysvinit.new/sysvinit.changes 2018-05-30 12:41:04.976892720 +0200
@@ -1,0 +2,5 @@
+Thu May 24 10:30:28 CEST 2018 - kukuk(a)suse.de
+
+- Use %license instead of %doc [bsc#1082318]
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ powerd.spec ++++++
--- /var/tmp/diff_new_pack.oGVUCr/_old 2018-05-30 12:41:05.764865531 +0200
+++ /var/tmp/diff_new_pack.oGVUCr/_new 2018-05-30 12:41:05.764865531 +0200
@@ -1,7 +1,7 @@
#
# spec file for package powerd
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
Version: 2.0.2
Release: 0
Summary: UPS monitoring daemon
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: System/Base
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: systemd-rpm-macros
@@ -81,7 +81,8 @@
%files -n powerd
%defattr (-,root,root,755)
-%doc README COPYING SUPPORTED FAQ powerd.conf.monitor powerd.conf.peer
+%license COPYING
+%doc README SUPPORTED FAQ powerd.conf.monitor powerd.conf.peer
/sbin/powerd
/sbin/detectups
%{_sbindir}/rcpowerd
++++++ sysvinit.spec ++++++
--- /var/tmp/diff_new_pack.oGVUCr/_old 2018-05-30 12:41:05.804864150 +0200
+++ /var/tmp/diff_new_pack.oGVUCr/_new 2018-05-30 12:41:05.808864012 +0200
@@ -1,7 +1,7 @@
#
# spec file for package sysvinit
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
Version: %{SIVER}
Release: 0
Summary: SysV-Style init
-License: GPL-2.0+
+License: GPL-2.0-or-later
Group: System/Base
BuildRequires: blog-devel
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -114,8 +114,8 @@
%files tools
%defattr (-,root,root,755)
-%doc COPYING COPYRIGHT doc/Propaganda
-%doc doc/Changelog doc/killproc
+%license COPYING COPYRIGHT
+%doc doc/Propaganda doc/Changelog doc/killproc
/bin/pidof
/bin/usleep
/bin/fsync
1
0