Package init

This commit is contained in:
zhengyaohui 2021-09-12 17:15:43 +08:00
parent 830d63bb6e
commit 5264a58fcb
8 changed files with 472 additions and 0 deletions

8
cron.daily Normal file
View File

@ -0,0 +1,8 @@
#!/bin/sh
set -e
if [ -e /etc/etckeeper/daily ] && [ -e /etc/etckeeper/etckeeper.conf ]; then
. /etc/etckeeper/etckeeper.conf
if [ "$AVOID_DAILY_AUTOCOMMITS" != "1" ]; then
/etc/etckeeper/daily
fi
fi

View File

@ -0,0 +1,162 @@
From 8266a4fb45621e08085c58537a531f33fc7eca74 Mon Sep 17 00:00:00 2001
From: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Date: Wed, 10 Apr 2019 00:19:14 +0100
Subject: [PATCH 1/2] DNF: stderr is not ours to log to (and doing so breaks
Ansible)
stderr does not belong to etckeeper-dnf
---------------------------------------
The Ansible dnf module uses the python dnf bindings. In contexts like
these, stdout/stderr is owned by the host app (Ansible). dnf should not
mess with stdout/stderr, unless the host app asks it to log there.
Specifically, we were breaking the JSON output of the Ansible dnf module.
This was only noticeable when the etckeeper message began with a "["
character. Ansible has a mechanism to try and skip header messages like
login banners. However, "[" is a valid character to start a JSON document.
https://unix.stackexchange.com/questions/511210/ansible-dnf-module-module-failure/
Solution
--------
Instead, log any non-zero exit status through the dnf logger.
For the pre-transaction etckeeper run, this message replaces an exception.
So we now avoid logging a traceback, which did not appear to add anything
useful. (In my testing, dnf was continued to install after the exception
was logged).
I have also added a warning message for the post-transaction etckeeper run.
I switched from os.system() to subprocess.call(). The latter interface
supports better error reporting. (When I tested os.system(), it returned
an errno number which was indistinguishable from an exit code).
etckeeper >/dev/null 2>&1
--------------------------
Any specific error messages from etckeeper are now discarded. Because
unfortunately, python conventions about passing text strings have been
somewhat unclear. It is an error to log strings if the encoding settings
of a registered logger cannot handle them. Because a "bad" character
causes the entire string to be discarded, and optionally an exception
printed to stderr. In a previous proposal I showed code that should be
correct in all expected cases. However, the length of comment required to
define "all expected cases" was not very reassuring.
That was on top of explaining that dnf has a workaround that will avoid
raising exceptions when arbitrary unicode is logged to stdout. My proposal
had to include that explanation, to show that we were not breaking a
system package manager.
It might sound strange to talk about error messages with characters
we cannot encode. But I have one word for you: "filenames".
(After the recent python PR #14008[1], logging.basicConfig() defaults
to errors='backslashreplace'. Also, errors= can be manually specified when
creating a lower-level logging "Handler". I think this will resolve the
problem in the future. It means that when programs are written for this
new version of python, it should be the responsibility of the log setup
code to prevent UnicodeEncodeError.)
[1] https://github.com/python/cpython/pull/14008
---
etckeeper-dnf/etckeeper.py | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/etckeeper-dnf/etckeeper.py b/etckeeper-dnf/etckeeper.py
index e8a1a51..69edd88 100644
--- a/etckeeper-dnf/etckeeper.py
+++ b/etckeeper-dnf/etckeeper.py
@@ -9,7 +9,7 @@
from dnfpluginscore import logger
-import os
+import subprocess
import dnf
@@ -17,20 +17,25 @@ class Etckeeper(dnf.Plugin):
name = 'etckeeper'
- def _out(self, msg):
- logger.debug('Etckeeper plugin: %s', msg)
+ def _run_command(self, command):
+ logger.debug('Etckeeper plugin: %s', command)
+ try:
+ with open("/dev/null", "wb") as devnull:
+ ret = subprocess.call(("etckeeper", command),
+ stdout=devnull, stderr=devnull,
+ close_fds=True)
+ if ret > 0:
+ logger.warning('"etckeeper %s" failed (exit code %d)' % (command, ret))
+ if ret < 0:
+ logger.warning('"etckeeper %s" died (signal %d)' % (command, -ret))
+ except OSError as err:
+ logger.warning('Failed to run "etckeeper %s": %s' % (command, err))
def resolved(self):
- self._out('pre transaction commit')
- command = '%s %s' % ('etckeeper', " pre-install")
- ret = os.system(command)
- if ret != 0:
- raise dnf.exceptions.Error('etckeeper returned %d' % (ret >> 8))
+ self._run_command("pre-install")
def transaction(self):
- self._out('post transaction commit')
- command = '%s %s > /dev/null' % ('etckeeper', "post-install")
- os.system(command)
+ self._run_command("post-install")
if __name__ == "__main__":
from distutils.core import setup
--
2.23.0
From 7cda9678b1e60c0495a2a522721b319843d5fae0 Mon Sep 17 00:00:00 2001
From: Alan Jenkins <alan.christopher.jenkins@gmail.com>
Date: Tue, 23 Apr 2019 20:15:01 +0100
Subject: [PATCH 2/2] Do not use dnfpluginscore.logger
dnfpluginscore is not core support for dnf plugins, it is just a
collection of "core plugins" for dnf. There is equally
dnfpluginsextras and dnfpluginsextras.logger.
A comment in dnf.logger comment says the logger name 'dnf.plugin' is "api".
So we can safely rely on that name.
Technically you can install etckeeper without the dnfpluginscore package
(at least I managed to run into this for python2, on a Fedora 29 system
which uses python3 for dnf by default).
---
etckeeper-dnf/etckeeper.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/etckeeper-dnf/etckeeper.py b/etckeeper-dnf/etckeeper.py
index 69edd88..d9dd2c3 100644
--- a/etckeeper-dnf/etckeeper.py
+++ b/etckeeper-dnf/etckeeper.py
@@ -7,11 +7,12 @@
# Distutils code below was copied from etckeeper-bzr distributed with v1.15
#
-from dnfpluginscore import logger
-
+import logging
import subprocess
import dnf
+logger = logging.getLogger('dnf.plugin')
+
class Etckeeper(dnf.Plugin):
--
2.23.0

BIN
etckeeper-1.18.16.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,34 @@
diff --git a/pre-commit.d/20warn-problem-files b/pre-commit.d/20warn-problem-files
index 6bd5c2b..7899268 100755
--- a/pre-commit.d/20warn-problem-files
+++ b/pre-commit.d/20warn-problem-files
@@ -1,19 +1,20 @@
#!/bin/sh
set -e
-exclude_internal () {
- egrep -v '(^|/)(\.git|\.hg|\.bzr|_darcs)/'
-}
+# (Note that when using this, the find expression must end with
+# -print or -exec, else the excluded directories will actually be
+# printed!)
+NOVCS='. -path ./.git -prune -o -path ./.bzr -prune -o -path ./.hg -prune -o -path ./_darcs -prune -o'
if [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
- special=$(find . ! -type d ! -type f ! -type l | exclude_internal) || true
- hardlinks=$(find . -type f ! -links 1 | exclude_internal ) || true
+ special=$(find $NOVCS ! -type d ! -type f ! -type l -print) || true
+ hardlinks=$(find $NOVCS -type f ! -links 1 -print) || true
elif [ "$VCS" = hg ]; then
- special=$(find . ! -type d ! -type f ! -type l | exclude_internal) || true
- hardlinks=$(find . -type f ! -links 1 -exec hg status {} \; | exclude_internal ) || true
+ special=$(find $NOVCS ! -type d ! -type f ! -type l -print) || true
+ hardlinks=$(find $NOVCS -type f ! -links 1 -exec hg status {} \; -print) || true
elif [ "$VCS" = git ]; then
- special=$(find . ! -type d ! -type f ! -type l -exec git ls-files --exclude-standard --cached --others {} + | exclude_internal) || true
- hardlinks=$(find . -type f ! -links 1 -exec git ls-files --exclude-standard --cached --others {} + | exclude_internal) || true
+ special=$(find $NOVCS ! -type d ! -type f ! -type l -exec git ls-files --exclude-standard --cached --others {} + -print) || true
+ hardlinks=$(find $NOVCS -type f ! -links 1 -exec git ls-files --exclude-standard --cached --others {} + -print) || true
else
special=""
fi

View File

@ -0,0 +1,14 @@
diff -up etckeeper-1.18.7/update-ignore.d/01update-ignore.orig etckeeper-1.18.7/update-ignore.d/01update-ignore
--- etckeeper-1.18.7/update-ignore.d/01update-ignore.orig 2017-08-13 12:31:57.360734395 +0200
+++ etckeeper-1.18.7/update-ignore.d/01update-ignore 2017-08-13 12:32:45.246242478 +0200
@@ -91,7 +91,9 @@ writefile () {
nl
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = "rpm" ]; then
comment "new and old versions of conffiles, stored by apt/rpm"
- ignore "*.rpm*"
+ ignore "*.rpmnew"
+ ignore "*.rpmorig"
+ ignore "*.rpmsave"
nl
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = "pacman-g2" -o "$LOWLEVEL_PACKAGE_MANAGER" = "pacman" -o "$LOWLEVEL_PACKAGE_MANAGER" = "pacmatic" ]; then
comment "new and old versions of conffiles, stored by pacman"

View File

@ -0,0 +1,52 @@
From b5919d7919dda614c3c3c76ba126f45e205494bd Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <xnox@ubuntu.com>
Date: Mon, 29 Apr 2019 14:11:09 +0100
Subject: [PATCH 1/3] Add breezy python3 plugin
---
Makefile | 3 +++
debian/changelog | 6 ++++++
debian/control | 6 +++---
etckeeper-brz/__init__.py | 34 ++++++++++++++++++++++++++++++++++
4 files changed, 46 insertions(+), 3 deletions(-)
create mode 100644 etckeeper-brz/__init__.py
Index: etckeeper-1.18.10/etckeeper-brz/__init__.py
===================================================================
--- /dev/null
+++ etckeeper-1.18.10/etckeeper-brz/__init__.py
@@ -0,0 +1,34 @@
+#
+# Breezy plugin that runs etckeeper pre-commit when necessary
+
+"""Runs etckeeper pre-commit when necessary."""
+
+from breezy.errors import BzrError
+import os
+
+def etckeeper_startcommit_hook(tree):
+ abspath = getattr(tree, "abspath", None)
+ if abspath is None or not os.path.exists(abspath(".etckeeper")):
+ # Only run the commit hook when this is an etckeeper branch
+ return
+ import subprocess
+ ret = subprocess.call(["etckeeper", "pre-commit", abspath(".")])
+ if ret != 0:
+ raise BzrError("etckeeper pre-commit failed")
+
+try:
+ from breezy.hooks import install_lazy_named_hook
+except ImportError:
+ from breezy.mutabletree import MutableTree
+ MutableTree.hooks.install_named_hook('start_commit',
+ etckeeper_startcommit_hook, 'etckeeper')
+else:
+ install_lazy_named_hook(
+ "breezy.mutabletree", "MutableTree.hooks",
+ 'start_commit', etckeeper_startcommit_hook, 'etckeeper')
+
+if __name__ == "__main__":
+ from distutils.core import setup
+ setup(name="brz-etckeeper",
+ packages=["breezy.plugins.etckeeper"],
+ package_dir={"breezy.plugins.etckeeper":"etckeeper-brz"})

View File

@ -0,0 +1,32 @@
diff -up etckeeper-1.18.7/Makefile.orig etckeeper-1.18.7/Makefile
--- etckeeper-1.18.7/Makefile.orig 2017-06-08 18:59:32.000000000 +0200
+++ etckeeper-1.18.7/Makefile 2017-06-12 22:58:50.802133039 +0200
@@ -15,13 +15,10 @@ CP=cp -R
INSTALL=install
INSTALL_EXE=${INSTALL}
INSTALL_DATA=${INSTALL} -m 0644
-PYTHON=python
FAKEROOT := $(shell command -v fakeroot 2> /dev/null)
TESTDIR := $(shell mktemp -u -d)
build: etckeeper.spec etckeeper.version
- -$(PYTHON) ./etckeeper-bzr/__init__.py build || echo "** bzr support not built"
- -$(PYTHON) ./etckeeper-dnf/etckeeper.py build || echo "** DNF support not built"
install: etckeeper.version
mkdir -p $(DESTDIR)$(etcdir)/etckeeper/ $(DESTDIR)$(vardir)/cache/etckeeper/
@@ -58,14 +55,10 @@ ifeq ($(HIGHLEVEL_PACKAGE_MANAGER),yum)
mkdir -p $(DESTDIR)$(etcdir)/yum/pluginconf.d
$(INSTALL_DATA) yum-etckeeper.conf $(DESTDIR)$(etcdir)/yum/pluginconf.d/etckeeper.conf
endif
-ifeq ($(HIGHLEVEL_PACKAGE_MANAGER),dnf)
- -$(PYTHON) ./etckeeper-dnf/etckeeper.py install --root=$(DESTDIR) ${PYTHON_INSTALL_OPTS} || echo "** DNF support not installed"
-endif
ifeq ($(HIGHLEVEL_PACKAGE_MANAGER),zypper)
mkdir -p $(DESTDIR)$(prefix)/lib/zypp/plugins/commit
$(INSTALL) zypper-etckeeper.py $(DESTDIR)$(prefix)/lib/zypp/plugins/commit/zypper-etckeeper.py
endif
- -$(PYTHON) ./etckeeper-bzr/__init__.py install --root=$(DESTDIR) ${PYTHON_INSTALL_OPTS} || echo "** bzr support not installed"
echo "** installation successful"
clean: etckeeper.spec etckeeper.version

170
etckeeper.spec Normal file
View File

@ -0,0 +1,170 @@
%{!?_pkgdocdir: %global _pkgdocdir %{_docdir}/%{name}-%{version}}
%global dnf_is_mandatory 1
Name: etckeeper
Version: 1.18.16
Release: 1
Summary: Store /etc in a SCM system (git, mercurial, bzr or darcs)
License: GPLv2+
URL: https://etckeeper.branchable.com/
Source0: https://git.joeyh.name/index.cgi/etckeeper.git/snapshot/%{name}-%{version}.tar.gz
Source2: cron.daily
Patch0: etckeeper-makefile-remove-python-plugins.patch
Patch1: etckeeper-1.18.7-fix-rpm-ignores.patch
Patch2: etckeeper-1.18.7-fix-hg-warnings.patch
Patch3: etckeeper-add-breezy-python3-plugin.patch
Patch4: etckeeper-1.18.12-fix-output-for-ansible.patch
BuildArch: noarch
BuildRequires: python3-markdown
Requires: git >= 1.6.1 perl-interpreter crontabs findutils hostname which
%if 0%{?dnf_is_mandatory}
Requires: %{name}-dnf = %{version}-%{release}
%endif
BuildRequires: systemd
Requires(post): systemd
Requires(preun): systemd
Requires(postun): systemd
%description
The etckeeper program is a tool to let /etc be stored in a git,
mercurial, bzr or darcs repository. It hooks into yum to automatically
commit changes made to /etc during package upgrades. It tracks file
metadata that version control systems do not normally support, but that
is important for /etc, such as the permissions of /etc/shadow. It's
quite modular and configurable, while also being simple to use if you
understand the basics of working with version control.
The default backend is git, if want to use a another backend please
install the appropriate tool (mercurial, darcs or bzr).
%{?bazaar: To use bazaar/breezy as backend, please also install the %{name}-%{bazaar} package.}
To start using the package please read %{_pkgdocdir}/README.
%if 0%{?with_brz}
%package brz
Summary: Support for bzr with etckeeper (via breezy)
BuildRequires: python3-devel brz
Requires: %{name} = %{version}-%{release} brz
%description brz
This package provides a brz (breezy) backend for etckeeper, if you want to use
etckeeper with (bzr) bazaar repositories, install this package.
%endif
%package dnf
Summary: DNF plugin for etckeeper support
BuildRequires: python3-devel
BuildRequires: dnf dnf-plugins-core make
Requires: %{name} = %{version}-%{release} dnf dnf-plugins-core
%description dnf
This package provides a DNF plugin for etckeeper. If you want to use
etckeeper with DNF, install this package.
%prep
%autosetup -p1
%if 0%{?with_yum}
sed -e 's|HIGHLEVEL_PACKAGE_MANAGER=.*|HIGHLEVEL_PACKAGE_MANAGER=yum|' \
%else
sed -e 's|HIGHLEVEL_PACKAGE_MANAGER=.*|HIGHLEVEL_PACKAGE_MANAGER=dnf|' \
%endif
-e 's|LOWLEVEL_PACKAGE_MANAGER=.*|LOWLEVEL_PACKAGE_MANAGER=rpm|' \
-i etckeeper.conf
sed -e 's|^prefix=.*|prefix=%{_prefix}|' \
-e 's|^bindir=.*|bindir=%{_bindir}|' \
-e 's|^etcdir=.*|etcdir=%{_sysconfdir}|' \
-e 's|^mandir=.*|mandir=%{_mandir}|' \
-e 's|^vardir=.*|vardir=%{_localstatedir}|' \
-e 's|^INSTALL=.*|INSTALL=install -p|' \
-e 's|^CP=.*|CP=cp -pR|' \
-e 's|^systemddir=.*|systemddir=%{_unitdir}|' \
-i Makefile
mkdir brz-plugin ; mv etckeeper-brz brz-plugin
mkdir dnf-plugin ; mv etckeeper-dnf dnf-plugin
%build
%make_build
%if 0%{?with_brz}
pushd brz-plugin
%define py_setup etckeeper-brz/__init__.py
%py3_build
popd
%endif
pushd dnf-plugin
%define py_setup etckeeper-dnf/etckeeper.py build
%py3_build
popd
`ls /usr/bin/ |grep "markdown"` -f README.html README.md
%install
%make_install
%if 0%{?with_brz}
pushd brz-plugin
%define py_setup etckeeper-brz/__init__.py
%py3_install
popd
%endif
pushd dnf-plugin
%define py_setup etckeeper-dnf/etckeeper.py build
%py3_install
popd
%if 0%{?dnf_is_mandatory}
sed -e 's|HIGHLEVEL_PACKAGE_MANAGER=.*|HIGHLEVEL_PACKAGE_MANAGER=dnf|' \
-i %{buildroot}%{_sysconfdir}/%{name}/%{name}.conf
%endif
install -D -p %{SOURCE2} %{buildroot}%{_sysconfdir}/cron.daily/%{name}
install -d %{buildroot}%{_localstatedir}/cache/%{name}
%post
if [ $1 -gt 1 ] ; then
%{_bindir}/%{name} update-ignore
fi
%systemd_post %{name}.service
%systemd_post %{name}.timer
%preun
%systemd_preun %{name}.service
%systemd_preun %{name}.timer
%postun
%systemd_postun %{name}.service
%systemd_postun %{name}.timer
%files
%doc README.html README.md
%license GPL
%{_bindir}/%{name}
%{_mandir}/man8/%{name}.8*
%dir %{_sysconfdir}/%{name}
%{_sysconfdir}/%{name}/*.d
%{_sysconfdir}/%{name}/daily
%config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
%config(noreplace) %{_sysconfdir}/cron.daily/%{name}
%dir %{_datadir}/bash-completion
%dir %{_datadir}/bash-completion/completions
%{_datadir}/bash-completion/completions/%{name}
%dir %{_datadir}/zsh
%dir %{_datadir}/zsh/vendor-completions
%{_datadir}/zsh/vendor-completions/_%{name}
%if 0%{?with_yum}
%dir %{_prefix}/lib/yum-plugins
%{_prefix}/lib/yum-plugins/%{name}.*
%dir %{_sysconfdir}/yum/pluginconf.d
%config(noreplace) %{_sysconfdir}/yum/pluginconf.d/%{name}.conf
%endif
%{_localstatedir}/cache/%{name}
%{_unitdir}/%{name}.service
%{_unitdir}/%{name}.timer
%if 0%{?with_brz}
%files brz
%dir %{python3_sitelib}/breezy/
%dir %{python3_sitelib}/breezy/plugins/
%{python3_sitelib}/breezy/plugins/%{name}/
%{python3_sitelib}/brz_%{name}-*.egg-info
%endif
%files dnf
%{python3_sitelib}/dnf-plugins/%{name}.py
%exclude %{python3_sitelib}/dnf-plugins/__init__.py
%{python3_sitelib}/dnf-plugins/__pycache__/%{name}.*
%exclude %{python3_sitelib}/dnf-plugins/__pycache__/__init__.*
%{python3_sitelib}/dnf_%{name}-*.egg-info
%changelog
* Tue Sep 7 2021 zhengyaohui <zhengyaohui1@huawei.com> - 1.18.16-1
- package init