Initial commit.
This commit is contained in:
17
etckeeper/commit.d/10vcs-test
Executable file
17
etckeeper/commit.d/10vcs-test
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
not_enabled_warning() {
|
||||
echo "etckeeper warning: etckeeper is not yet enabled for $(pwd)" >&2
|
||||
echo "etckeeper warning: run etckeeper init to enable it" >&2
|
||||
}
|
||||
|
||||
if [ "$VCS" = git ] && [ ! -d .git ]; then
|
||||
not_enabled_warning
|
||||
elif [ "$VCS" = hg ] && [ ! -d .hg ]; then
|
||||
not_enabled_warning
|
||||
elif [ "$VCS" = bzr ] && [ ! -d .bzr ]; then
|
||||
not_enabled_warning
|
||||
elif [ "$VCS" = darcs ] && [ ! -d _darcs ]; then
|
||||
not_enabled_warning
|
||||
fi
|
||||
1
etckeeper/commit.d/20store-metadata
Symbolic link
1
etckeeper/commit.d/20store-metadata
Symbolic link
@@ -0,0 +1 @@
|
||||
../pre-commit.d/30store-metadata
|
||||
8
etckeeper/commit.d/30bzr-add
Executable file
8
etckeeper/commit.d/30bzr-add
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = bzr ] && [ -d .bzr ]; then
|
||||
if ! bzr add -q .; then
|
||||
echo "etckeeper warning: bzr add failed" >&2
|
||||
fi
|
||||
fi
|
||||
14
etckeeper/commit.d/30darcs-add
Executable file
14
etckeeper/commit.d/30darcs-add
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = darcs ] && [ -d _darcs ]; then
|
||||
rc=0
|
||||
res=$( darcs add -qr . 2>&1 ) || rc=$?
|
||||
if test $rc -ne 0; then
|
||||
if ! test $rc -eq 2 -a "${res%No files were added}" != "$res"; then
|
||||
printf "%s" "$res"
|
||||
echo "etckeeper warning: darcs add failed" >&2
|
||||
fi
|
||||
fi
|
||||
unset rc res
|
||||
fi
|
||||
8
etckeeper/commit.d/30git-add
Executable file
8
etckeeper/commit.d/30git-add
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ] && [ -d .git ]; then
|
||||
if ! git add --all; then
|
||||
echo "etckeeper warning: git add --all" >&2
|
||||
fi
|
||||
fi
|
||||
8
etckeeper/commit.d/30hg-addremove
Executable file
8
etckeeper/commit.d/30hg-addremove
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = hg ] && [ -d .hg ]; then
|
||||
if ! hg addremove .; then
|
||||
echo "etckeeper warning: hg addremove failed" >&2
|
||||
fi
|
||||
fi
|
||||
142
etckeeper/commit.d/50vcs-commit
Executable file
142
etckeeper/commit.d/50vcs-commit
Executable file
@@ -0,0 +1,142 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
cleanup () {
|
||||
if [ -n "$logfile" ]; then
|
||||
rm -f "$logfile"
|
||||
fi
|
||||
}
|
||||
if [ -n "$1" ]; then
|
||||
trap cleanup EXIT
|
||||
logfile="$(mktemp -t etckeeper-$VCS.XXXXXXXXXX)"
|
||||
if [ "x$1" = "x--stdin" ]; then
|
||||
cat > "$logfile"
|
||||
else
|
||||
sed '1s/^-m \{0,1\}//' >"$logfile" <<-EOF
|
||||
$*
|
||||
EOF
|
||||
fi
|
||||
else
|
||||
logfile=""
|
||||
fi
|
||||
|
||||
hostname=`hostname 2>/dev/null || cat /etc/hostname`
|
||||
hostname="${hostname%%.*}"
|
||||
dnsdomainname=`dnsdomainname 2>/dev/null || true`
|
||||
if [ -n "$dnsdomainname" ]; then
|
||||
hostname="$hostname.$dnsdomainname"
|
||||
fi
|
||||
|
||||
ORIG_USER=$USER
|
||||
USER=
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
USER="$SUDO_USER"
|
||||
else
|
||||
# try to check tty ownership, in case user su'd to root
|
||||
TTY="$(tty 2>/dev/null || true)"
|
||||
if [ -n "$TTY" ] && [ -c "$TTY" ]; then
|
||||
USER="$(find "$TTY" -printf "%u")"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$VCS" = git ] && [ -d .git ]; then
|
||||
# When not su'd to root, still set environment variables,
|
||||
# since git's own code to determine the author and committer
|
||||
# has several edge cases where it fails and would prevent the
|
||||
# commit.
|
||||
if [ -z "$USER" ]; then
|
||||
USER="$(whoami)"
|
||||
fi
|
||||
if [ -n "$USER" ]; then
|
||||
# Use user.name and user.email from the gitconfig belonging
|
||||
# to USER.
|
||||
USER_HOME="$(getent passwd "$USER" | cut -d: -f6)"
|
||||
if [ -n "$USER_HOME" ] && [ -e "$USER_HOME/.gitconfig" ]; then
|
||||
if [ -z "$GIT_AUTHOR_NAME" ]; then
|
||||
GIT_AUTHOR_NAME="$(git config -f "$USER_HOME/.gitconfig" user.name)" || true
|
||||
export GIT_AUTHOR_NAME
|
||||
fi
|
||||
if [ -z "$GIT_AUTHOR_EMAIL" ]; then
|
||||
GIT_AUTHOR_EMAIL="$(git config -f "$USER_HOME/.gitconfig" user.email)" || true
|
||||
export GIT_AUTHOR_EMAIL
|
||||
fi
|
||||
fi
|
||||
if [ -z "$GIT_AUTHOR_NAME" ] || [ -z "$GIT_AUTHOR_EMAIL" ]; then
|
||||
if [ -n "$USER_HOME" ] && [ -e "$USER_HOME/.config/git/config" ]; then
|
||||
if [ -z "$GIT_AUTHOR_NAME" ]; then
|
||||
GIT_AUTHOR_NAME="$(git config -f "$USER_HOME/.config/git/config" user.name)" || true
|
||||
export GIT_AUTHOR_NAME
|
||||
fi
|
||||
if [ -z "$GIT_AUTHOR_EMAIL" ]; then
|
||||
GIT_AUTHOR_EMAIL="$(git config -f "$USER_HOME/.config/git/config" user.email)" || true
|
||||
export GIT_AUTHOR_EMAIL
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$GIT_COMMITTER_EMAIL" ]; then
|
||||
GIT_COMMITTER_EMAIL="$(git config --global user.email)" || true
|
||||
export GIT_COMMITTER_EMAIL
|
||||
fi
|
||||
if [ -z "$GIT_AUTHOR_NAME" ]; then
|
||||
GIT_AUTHOR_NAME="$USER"
|
||||
export GIT_AUTHOR_NAME
|
||||
fi
|
||||
if [ -z "$GIT_AUTHOR_EMAIL" ]; then
|
||||
GIT_AUTHOR_EMAIL="$USER@$hostname"
|
||||
export GIT_AUTHOR_EMAIL
|
||||
fi
|
||||
if [ -z "$GIT_COMMITTER_EMAIL" ]; then
|
||||
GIT_COMMITTER_EMAIL=`whoami`"@$hostname"
|
||||
export GIT_COMMITTER_EMAIL
|
||||
fi
|
||||
fi
|
||||
|
||||
# gc ten times more frequently than the default
|
||||
# (unless some other config is set)
|
||||
GIT_GC_OPTIONS=
|
||||
if ! git config gc.auto >/dev/null; then
|
||||
GIT_GC_OPTIONS="-c gc.auto=670"
|
||||
fi
|
||||
|
||||
if [ -n "$logfile" ]; then
|
||||
git $GIT_GC_OPTIONS commit $GIT_COMMIT_OPTIONS -F "$logfile"
|
||||
else
|
||||
git $GIT_GC_OPTIONS commit $GIT_COMMIT_OPTIONS
|
||||
fi
|
||||
elif [ "$VCS" = hg ] && [ -d .hg ]; then
|
||||
if [ -n "$USER" ]; then
|
||||
LOGNAME="$USER"
|
||||
export LOGNAME
|
||||
fi
|
||||
if [ -z "$HGUSER" ]; then
|
||||
HGUSER="$USER@$hostname"
|
||||
export HGUSER
|
||||
fi
|
||||
if [ -n "$logfile" ]; then
|
||||
hg commit $HG_COMMIT_OPTIONS -l "$logfile"
|
||||
else
|
||||
hg commit $HG_COMMIT_OPTIONS
|
||||
fi
|
||||
elif [ "$VCS" = bzr ] && [ -d .bzr ]; then
|
||||
if [ -z "$EMAIL" ] && [ -n "$USER" ]; then
|
||||
EMAIL="$USER <$USER@$hostname>"
|
||||
export EMAIL
|
||||
else
|
||||
bzr whoami >/dev/null 2>&1 || export EMAIL="$ORIG_USER <$ORIG_USER@$hostname>"
|
||||
fi
|
||||
if [ -n "$logfile" ]; then
|
||||
bzr commit $BZR_COMMIT_OPTIONS -F "$logfile"
|
||||
else
|
||||
bzr commit $BZR_COMMIT_OPTIONS
|
||||
fi
|
||||
elif [ "$VCS" = darcs ] && [ -d _darcs ]; then
|
||||
if [ -z "$USER" ]; then
|
||||
USER=root
|
||||
fi
|
||||
if [ -n "$logfile" ]; then
|
||||
darcs record --author="$USER" $DARCS_COMMIT_OPTIONS --logfile="$logfile"
|
||||
else
|
||||
darcs record --author="$USER" $DARCS_COMMIT_OPTIONS
|
||||
fi
|
||||
fi
|
||||
14
etckeeper/commit.d/99push
Executable file
14
etckeeper/commit.d/99push
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
if [ -n "$PUSH_REMOTE" ]; then
|
||||
if [ "$VCS" = git ] && [ -d .git ]; then
|
||||
for REMOTE in $PUSH_REMOTE; do
|
||||
git push "$REMOTE" || true
|
||||
done
|
||||
elif [ "$VCS" = hg ] && [ -d .hg ]; then
|
||||
for REMOTE in $PUSH_REMOTE; do
|
||||
hg push "$REMOTE" || true
|
||||
done
|
||||
else
|
||||
echo "PUSH_REMOTE not yet supported for $VCS" >&2
|
||||
fi
|
||||
fi
|
||||
3
etckeeper/commit.d/README
Normal file
3
etckeeper/commit.d/README
Normal file
@@ -0,0 +1,3 @@
|
||||
Files in this directory are run when there might be changes to commit.
|
||||
(Before and after packages are installed, upgraded, etc.)
|
||||
They should commit changes and new files in /etc to repository.
|
||||
17
etckeeper/daily
Executable file
17
etckeeper/daily
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
# Script that can be run daily to autocommit /etc changes.
|
||||
set -e
|
||||
if [ -x /usr/bin/etckeeper ] && [ -e /etc/etckeeper/etckeeper.conf ]; then
|
||||
# avoid autocommit if an install run is in progress
|
||||
lockfile=/var/cache/etckeeper/packagelist.pre-install
|
||||
if [ -e "$lockfile" ] && [ -n "$(find "$lockfile" -mtime +1)" ]; then
|
||||
rm -f "$lockfile" # stale
|
||||
fi
|
||||
if [ ! -e "$lockfile" ]; then
|
||||
AVOID_SPECIAL_FILE_WARNING=1
|
||||
export AVOID_SPECIAL_FILE_WARNING
|
||||
if etckeeper unclean; then
|
||||
etckeeper commit "daily autocommit" >/dev/null
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
45
etckeeper/etckeeper.conf
Normal file
45
etckeeper/etckeeper.conf
Normal file
@@ -0,0 +1,45 @@
|
||||
# The VCS to use.
|
||||
#VCS="hg"
|
||||
VCS="git"
|
||||
#VCS="bzr"
|
||||
#VCS="darcs"
|
||||
|
||||
# Options passed to git commit when run by etckeeper.
|
||||
GIT_COMMIT_OPTIONS=""
|
||||
|
||||
# Options passed to hg commit when run by etckeeper.
|
||||
HG_COMMIT_OPTIONS=""
|
||||
|
||||
# Options passed to bzr commit when run by etckeeper.
|
||||
BZR_COMMIT_OPTIONS=""
|
||||
|
||||
# Options passed to darcs record when run by etckeeper.
|
||||
DARCS_COMMIT_OPTIONS="-a"
|
||||
|
||||
# Etckeeper includes both a cron job and a systemd timer, which each
|
||||
# can commit exiting changes to /etc automatically once per day.
|
||||
# To enable the systemd timer, run: systemctl enable etckeeper.timer
|
||||
# The cron job is enabled by default; to disable it, uncomment this next line.
|
||||
#AVOID_DAILY_AUTOCOMMITS=1
|
||||
|
||||
# Uncomment the following to avoid special file warning
|
||||
# (the option is enabled automatically for daily autocommits regardless).
|
||||
#AVOID_SPECIAL_FILE_WARNING=1
|
||||
|
||||
# Uncomment to avoid etckeeper committing existing changes to
|
||||
# /etc before installation. It will cancel the installation,
|
||||
# so you can commit the changes by hand.
|
||||
#AVOID_COMMIT_BEFORE_INSTALL=1
|
||||
|
||||
# The high-level package manager that's being used.
|
||||
# (apt, pacman, pacman-g2, yum, dnf, zypper, apk etc)
|
||||
HIGHLEVEL_PACKAGE_MANAGER=dnf
|
||||
|
||||
# The low-level package manager that's being used.
|
||||
# (dpkg, rpm, pacman, pacmatic, pacman-g2, apk etc)
|
||||
LOWLEVEL_PACKAGE_MANAGER=yum
|
||||
|
||||
# To push each commit to a remote, put the name of the remote here.
|
||||
# (eg, "origin" for git). Space-separated lists of multiple remotes
|
||||
# also work (eg, "origin gitlab github" for git).
|
||||
PUSH_REMOTE="origin"
|
||||
14
etckeeper/init.d/10restore-metadata
Executable file
14
etckeeper/init.d/10restore-metadata
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Note that metastore doesn't check that the .metastore file only changes
|
||||
# perms of files in the current directory. It's ok to trust the .metastore
|
||||
# file won't do anything shady, because, as documented, etckeeper-init
|
||||
# should only be run on repositories you trust.
|
||||
if [ -e .metadata ]; then
|
||||
if command -v metastore >/dev/null; then
|
||||
metastore --apply --mtime
|
||||
else
|
||||
echo "etckeeper warning: legacy .metastore file is present but metastore is not installed" >&2
|
||||
fi
|
||||
fi
|
||||
22
etckeeper/init.d/20restore-etckeeper
Executable file
22
etckeeper/init.d/20restore-etckeeper
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Used by .etckeeper to run a command if the file it acts on
|
||||
# (the last parameter) exists.
|
||||
maybe () {
|
||||
command="$1"
|
||||
shift 1
|
||||
|
||||
if eval [ -e "\"\$$#\"" ]; then
|
||||
"$command" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Yes, this runs code from the repository. As documented, etckeeper-init
|
||||
# should only be run on repositories you trust.
|
||||
if [ -e .etckeeper ]; then
|
||||
. ./.etckeeper
|
||||
else
|
||||
touch .etckeeper
|
||||
chmod 600 .etckeeper
|
||||
fi
|
||||
18
etckeeper/init.d/40vcs-init
Executable file
18
etckeeper/init.d/40vcs-init
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
description="$(hostname 2>/dev/null || cat /etc/hostname) /etc repository"
|
||||
if [ "$VCS" = git ] && [ ! -e .git ]; then
|
||||
git init
|
||||
echo "$description" > .git/description
|
||||
elif [ "$VCS" = hg ] && [ ! -e .hg ]; then
|
||||
hg init
|
||||
echo "[web]" > .hg/hgrc
|
||||
echo "description = $description" >> .hg/hgrc
|
||||
elif [ "$VCS" = bzr ] && [ ! -e .bzr ]; then
|
||||
bzr init
|
||||
bzr nick "$description"
|
||||
elif [ "$VCS" = darcs ] && [ ! -e _darcs ]; then
|
||||
darcs initialize
|
||||
echo "$description" > _darcs/prefs/motd
|
||||
fi
|
||||
4
etckeeper/init.d/50vcs-ignore
Executable file
4
etckeeper/init.d/50vcs-ignore
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
etckeeper update-ignore -a || true
|
||||
12
etckeeper/init.d/50vcs-perm
Executable file
12
etckeeper/init.d/50vcs-perm
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ]; then
|
||||
chmod 700 .git
|
||||
elif [ "$VCS" = hg ]; then
|
||||
chmod 700 .hg
|
||||
elif [ "$VCS" = bzr ]; then
|
||||
chmod 700 .bzr
|
||||
elif [ "$VCS" = darcs ]; then
|
||||
chmod 700 _darcs
|
||||
fi
|
||||
49
etckeeper/init.d/50vcs-pre-commit-hook
Executable file
49
etckeeper/init.d/50vcs-pre-commit-hook
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
case "$VCS" in
|
||||
git)
|
||||
if [ -x .git/hooks/pre-commit ]; then
|
||||
if ! grep -q "etckeeper pre-commit" .git/hooks/pre-commit; then
|
||||
echo "etckeeper warning: .git/hooks/pre-commit needs to be manually modified to run: etckeeper pre-commit -d `pwd`" >&2
|
||||
fi
|
||||
else
|
||||
cat >.git/hooks/pre-commit <<EOF
|
||||
#!/bin/sh
|
||||
# pre-commit hook for etckeeper, to store metadata and do sanity checks
|
||||
set -e
|
||||
etckeeper pre-commit -d `pwd`
|
||||
EOF
|
||||
chmod +x .git/hooks/pre-commit
|
||||
fi
|
||||
;;
|
||||
hg)
|
||||
if [ -e .hg/hgrc ] && grep "^\[hooks\]" .hg/hgrc; then
|
||||
if ! grep "^pre-commit" .hg/hgrc | grep -q "etckeeper pre-commit"; then
|
||||
echo "etckeeper warning: [hooks] section in .hg/hgrc needs to be manually modified to contain: pre-commit = etckeeper pre-commit -d `pwd`" >&2
|
||||
fi
|
||||
else
|
||||
touch .hg/hgrc
|
||||
cat >>.hg/hgrc <<EOF
|
||||
[hooks]
|
||||
# pre-commit hook for etckeeper, to store metadata and do sanity checks
|
||||
pre-commit = etckeeper pre-commit -d `pwd`
|
||||
EOF
|
||||
fi
|
||||
;;
|
||||
darcs)
|
||||
if [ -e _darcs/prefs/defaults ]; then
|
||||
if ! ( grep -q "record prehook etckeeper pre-commit" _darcs/prefs/defaults &&
|
||||
grep -q "whatsnew prehook etckeeper pre-commit" _darcs/prefs/defaults ); then
|
||||
echo "etckeeper warning: _darcs/prefs/defaults needs to be manually modified to run: etckeeper pre-commit -d `pwd`" >&2
|
||||
fi
|
||||
else
|
||||
cat >_darcs/prefs/defaults <<EOF
|
||||
record prehook etckeeper pre-commit -d `pwd`
|
||||
record run-prehook
|
||||
whatsnew prehook etckeeper pre-commit -d `pwd`
|
||||
whatsnew run-prehook
|
||||
EOF
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
48
etckeeper/init.d/60darcs-deleted-symlinks
Executable file
48
etckeeper/init.d/60darcs-deleted-symlinks
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
filter_ignore() {
|
||||
if [ "$VCS" = darcs ]; then
|
||||
ignorefile=.darcsignore
|
||||
fi
|
||||
|
||||
if [ "$VCS" = darcs ] && [ -e "$ignorefile" ]; then
|
||||
# Spaces embedded into patterns would break it.
|
||||
# But really, why would anyone want to use ' ' instead of '\s' ?
|
||||
#patterns=$( grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" | xargs -n 1 printf " -e %s" )
|
||||
#grep -Ev $patterns
|
||||
#unset patterns
|
||||
# Alternative using a temp file
|
||||
patternsfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
|
||||
grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$patternsfile" || true
|
||||
grep -Evf "$patternsfile"
|
||||
rm -f "$patternsfile"
|
||||
unset patternsfile
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
if [ "$VCS" = darcs ];then
|
||||
NOVCS='. -path ./.git -prune -o -path ./.bzr -prune -o -path ./.hg -prune -o -path ./_darcs -prune -o'
|
||||
|
||||
# We assume that if .etckeeper is empty this is the first run
|
||||
if [ -s .etckeeper ]; then
|
||||
linksindex="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
|
||||
grep '^ln -s' .etckeeper | while IFS="'" read n n n link n; do
|
||||
printf "%s\n" "$link" >> "$linksindex"
|
||||
done
|
||||
|
||||
# Warn about symbolic links that shouldn't exist
|
||||
if links=$( find $NOVCS -type l -print | filter_ignore | grep -vFf "$linksindex" ); then
|
||||
printf "%s\n%s\n" \
|
||||
"The following symbolic links should not exist:" \
|
||||
"$links" >&2
|
||||
fi
|
||||
|
||||
rm -f "$linksindex"
|
||||
unset links linksindex
|
||||
fi
|
||||
|
||||
fi
|
||||
27
etckeeper/init.d/70vcs-add
Executable file
27
etckeeper/init.d/70vcs-add
Executable file
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ]; then
|
||||
if ! git add .; then
|
||||
echo "etckeeper warning: git add failed" >&2
|
||||
fi
|
||||
elif [ "$VCS" = hg ]; then
|
||||
if ! hg add .; then
|
||||
echo "etckeeper warning: hg add failed" >&2
|
||||
fi
|
||||
elif [ "$VCS" = bzr ]; then
|
||||
if ! bzr add .; then
|
||||
echo "etckeeper warning: bzr add failed" >&2
|
||||
fi
|
||||
elif [ "$VCS" = darcs ]; then
|
||||
# Don't warn if all the files were already added.
|
||||
rc=0
|
||||
res=$( darcs add -qr . 2>&1 ) || rc=$?
|
||||
if test $rc -ne 0; then
|
||||
if ! test $rc -eq 2 -a "${res%No files were added}" != "$res"; then
|
||||
printf "%s" "$res"
|
||||
echo "etckeeper warning: darcs add failed" >&2
|
||||
fi
|
||||
fi
|
||||
unset rc res
|
||||
fi
|
||||
13
etckeeper/init.d/README
Normal file
13
etckeeper/init.d/README
Normal file
@@ -0,0 +1,13 @@
|
||||
Executable files in this directory are run to initialise the working directory
|
||||
for use by etckeeper. If the working directory is not already in version
|
||||
control, that includes setting up the version control, but not actually
|
||||
committing anything. If the working directory is in version control,
|
||||
it includes applying stored metadata to the checked out files in the
|
||||
working directory.
|
||||
|
||||
Please be careful to *never* overwrite existing files/directories
|
||||
in the working directory (or use absolute care when doing so). If a file
|
||||
you need to write already exists, check if its contents are sane, and
|
||||
if not, emit a warning on stderr.
|
||||
|
||||
If initialisation fails, exit nonzero and no later files will be run.
|
||||
32
etckeeper/list-installed.d/50list-installed
Executable file
32
etckeeper/list-installed.d/50list-installed
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
if [ "$1" = fmt ]; then
|
||||
# If the list format changes, change the fmt
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = dpkg ]; then
|
||||
echo 2
|
||||
else
|
||||
echo ""
|
||||
fi
|
||||
else
|
||||
# Keep the sort order the same at all times.
|
||||
LC_COLLATE=C
|
||||
export LC_COLLATE
|
||||
unset LC_ALL
|
||||
|
||||
# Output to stdout a *sorted* list of all currently installed
|
||||
# (or removed but still with config-files) packages, in the
|
||||
# format "package version\n" (or something similar).
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = dpkg ]; then
|
||||
dpkg-query -W -f '${Status}\t${Package} ${Version} ${Architecture}\n' | \
|
||||
egrep '(ok installed|ok config-files)' | cut -f2,3
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = rpm ]; then
|
||||
rpm -qa --qf "%|epoch?{%{epoch}}:{0}|:%{name}-%{version}-%{release}.%{arch}\n" | sort
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = pacman ]; then
|
||||
pacman -Q
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = pacmatic ]; then
|
||||
pacmatic -Q
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = pkgng ]; then
|
||||
pkg info -E "*"
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = apk ]; then
|
||||
apk info -v | sort
|
||||
fi
|
||||
fi
|
||||
91
etckeeper/post-install.d/50vcs-commit
Executable file
91
etckeeper/post-install.d/50vcs-commit
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
pl="/var/cache/etckeeper/packagelist"
|
||||
|
||||
# Parent process is etckeeper
|
||||
# (Only procps ps is currently supported, others will fail,
|
||||
# so this may end up empty.)
|
||||
ETCKEEPER_PID=$( ps --no-headers -o ppid "${PPID}" 2>/dev/null | sed 's/^ *//' )
|
||||
|
||||
# Find the parent of etckeeper and get the command line of the process
|
||||
if ! [ -z "${ETCKEEPER_PID}" ]; then
|
||||
ETCKEEPER_PPID=$( ps --no-headers -o ppid "${ETCKEEPER_PID}" | sed 's/^ *//' )
|
||||
ETCKEEPER_PARENT_COMMAND_LINE=$( ps --no-headers -o args "${ETCKEEPER_PPID}" )
|
||||
fi
|
||||
|
||||
get_changes () {
|
||||
if [ "$VCS" = git ]; then
|
||||
git diff --stat | grep '|' | cut -d'|' -f1 | cut -b2-
|
||||
git ls-files --exclude-standard --others
|
||||
fi
|
||||
if [ "$VCS" = hg ]; then
|
||||
hg status --no-status
|
||||
fi
|
||||
if [ "$VCS" = bzr ]; then
|
||||
bzr status -S | cut -b5-
|
||||
fi
|
||||
if [ "$VCS" = darcs ]; then
|
||||
# ignore ' file -> file' lines for moved files
|
||||
# trim ' -M +N rP' from change summary
|
||||
darcs whatsnew --summary | grep -v '^ .* -> ' | cut -d' ' -f2- | sed 's/ [-+r][0-9]\+//g;s/^\.\///'
|
||||
# lines beginning with 'a' show unversioned files
|
||||
darcs whatsnew --look-for-adds --boring --summary | grep '^a' | cut -d' ' -f2- | sed 's/^\.\///'
|
||||
fi
|
||||
}
|
||||
|
||||
get_changed_packages () {
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = dpkg ]; then
|
||||
get_changes | sed 's/^/\/etc\//;s/\s*$//' | xargs -d '\n' dpkg 2>/dev/null -S | cut -d':' -f1 | sed 's/, /\n/g'
|
||||
fi
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = rpm ]; then
|
||||
# if output contains file path, file was not found
|
||||
get_changes | sed 's/^/\/etc\//;s/\s*$//' | xargs -d '\n' rpm --qf '%{NAME}\n' -qf | grep -v "/etc/"
|
||||
fi
|
||||
# is it even possible to use pacmatic without pacman?
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = pacman -o "$LOWLEVEL_PACKAGE_MANAGER" = pacmatic ]; then
|
||||
get_changes | sed 's/^/\/etc\//;s/\s*$//' | xargs -d '\n' pacman 2>/dev/null -Qo | rev | cut -d' ' -f1-2 | rev | cut -d' ' -f1
|
||||
fi
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = pkgng ]; then
|
||||
get_changes | sed 's/^/\/etc\//;s/\s*$//' | xargs -d '\n' pkg which --quiet | rev | cut -d'-' -f2- | rev
|
||||
fi
|
||||
}
|
||||
|
||||
if etckeeper unclean; then
|
||||
if [ -z "${ETCKEEPER_PARENT_COMMAND_LINE}" ]; then
|
||||
message="committing changes in /etc after $HIGHLEVEL_PACKAGE_MANAGER run"
|
||||
else
|
||||
message="committing changes in /etc made by \"$ETCKEEPER_PARENT_COMMAND_LINE\""
|
||||
fi
|
||||
|
||||
set +e
|
||||
if [ -e $pl.pre-install ] && [ "$(cat $pl.fmt 2>/dev/null || true)" = "$(etckeeper list-installed fmt)" ]; then
|
||||
(
|
||||
echo "$message"
|
||||
echo
|
||||
get_changed_packages | sort | uniq > $pl.found-pkgs
|
||||
if [ -s $pl.found-pkgs ]; then
|
||||
sed -i 's/^/^[-+]/;s/$/ /' $pl.found-pkgs
|
||||
etckeeper list-installed | diff -U0 $pl.pre-install - | tail -n+4 | egrep '^[-+]' | grep -f $pl.found-pkgs > $pl.found-packages
|
||||
if [ -s $pl.found-packages ]; then
|
||||
echo "Packages with configuration changes:"
|
||||
cat $pl.found-packages || true
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
echo "Package changes:"
|
||||
etckeeper list-installed | diff -U0 $pl.pre-install - | tail -n+4 | egrep '^[-+]' || true
|
||||
) | etckeeper commit --stdin
|
||||
else
|
||||
etckeeper commit "$(printf "$message")"
|
||||
fi
|
||||
status=$?
|
||||
set -e
|
||||
|
||||
if [ "$status" != 0 ]; then
|
||||
echo "warning: etckeeper failed to commit changes in /etc using $VCS" >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -f $pl.pre-install $pl.fmt
|
||||
rm -f $pl.found-pkgs $pl.found-packages
|
||||
2
etckeeper/post-install.d/README
Normal file
2
etckeeper/post-install.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
Files in this directory are run after packages are installed, upgraded, etc.
|
||||
They should commit changes and new files in /etc to repository.
|
||||
31
etckeeper/pre-commit.d/20warn-problem-files
Executable file
31
etckeeper/pre-commit.d/20warn-problem-files
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# (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 $NOVCS ! -type d ! -type f ! -type l -print) || true
|
||||
hardlinks=$(find $NOVCS -type f ! -links 1 -print) || true
|
||||
elif [ "$VCS" = hg ]; then
|
||||
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 $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
|
||||
|
||||
if [ -n "$special" ] && [ -z "$AVOID_SPECIAL_FILE_WARNING" ]; then
|
||||
echo "etckeeper warning: special files could cause problems with $VCS:" >&2
|
||||
echo "$special" >&2
|
||||
fi
|
||||
if [ -n "$hardlinks" ] && [ -z "$AVOID_SPECIAL_FILE_WARNING" ]; then
|
||||
echo "etckeeper warning: hardlinked files could cause problems with $VCS:" >&2
|
||||
echo "$hardlinks" >&2
|
||||
fi
|
||||
|
||||
true
|
||||
171
etckeeper/pre-commit.d/30store-metadata
Executable file
171
etckeeper/pre-commit.d/30store-metadata
Executable file
@@ -0,0 +1,171 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Keep the sort order the same at all times.
|
||||
LC_COLLATE=C
|
||||
export LC_COLLATE
|
||||
unset LC_ALL
|
||||
|
||||
filter_ignore() {
|
||||
case "$VCS" in
|
||||
darcs) ignorefile=.darcsignore ;;
|
||||
git) ignorefile=.gitignore ;;
|
||||
esac
|
||||
|
||||
if [ -n "$ignorefile" ] && [ -e "$ignorefile" ]; then
|
||||
listfile="$( mktemp -t etckeeper-$VCS.XXXXXXXXXX )"
|
||||
case "$VCS" in
|
||||
darcs)
|
||||
grep -v '^[[:space:]]*\(#\|$\)' "$ignorefile" > "$listfile" || true
|
||||
grep -Evf "$listfile"
|
||||
;;
|
||||
git)
|
||||
(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | sort | uniq > "$listfile" || true
|
||||
if [ -s "$listfile" ]; then
|
||||
sed 's/^\.\///' | grep -xFvf "$listfile"
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
rm -f "$listfile"
|
||||
unset listfile
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
|
||||
shellquote() {
|
||||
# Single quotes text, escaping existing single quotes.
|
||||
sed -e "s/'/'\"'\"'/g" -e "s/^/'/" -e "s/$/'/"
|
||||
}
|
||||
|
||||
generate_metadata() {
|
||||
# This function generates the script commands to fix any file
|
||||
# ownerships that aren't owner=root, group=root, as well as to
|
||||
# store the permissions of files.
|
||||
# The script is produced on stdout. Errors go to stderr.
|
||||
#
|
||||
# The script can use a 'maybe' function, which only runs a command
|
||||
# if the file in its last argument exists.
|
||||
|
||||
# We want files in the directory containing VCS data
|
||||
# but we want find to ignore the VCS files themselves.
|
||||
#
|
||||
# (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" = git ] || [ "$VCS" = hg ]; then
|
||||
# These version control systems do not track directories,
|
||||
# so empty directories must be stored specially.
|
||||
find $NOVCS -type d -empty -print |
|
||||
sort | shellquote | sed -e "s/^/mkdir -p /"
|
||||
fi
|
||||
|
||||
if [ "$VCS" = darcs ]; then
|
||||
# This version control system does not track symlinks,
|
||||
# so they must be stored specially.
|
||||
find $NOVCS -type l -print | sort | filter_ignore | while read link; do
|
||||
dest=$( readlink "$link" )
|
||||
printf "ln -sf '%s' '%s'\n" "$(echo "$dest" | shellquote)" "$(echo "$link" | shellquote)"
|
||||
done
|
||||
fi
|
||||
|
||||
# Store things that don't have the default user or group.
|
||||
# Store all file modes, in case the user has an unusual umask.
|
||||
find $NOVCS \( -type f -or -type d \) -print | filter_ignore | sort | maybe_chmod_chown
|
||||
|
||||
# We don't handle xattrs.
|
||||
# Maybe check for getfattr/setfattr and use them if they're available?
|
||||
}
|
||||
|
||||
maybe_chmod_chown() {
|
||||
if command -v perl >/dev/null; then
|
||||
perl -ne '
|
||||
BEGIN { $q=chr(39) }
|
||||
sub uidname {
|
||||
my $want=shift;
|
||||
if (exists $uidcache{$want}) {
|
||||
return $uidcache{$want};
|
||||
}
|
||||
my $name=scalar getpwuid($want);
|
||||
return $uidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
sub gidname {
|
||||
my $want=shift;
|
||||
if (exists $gidcache{$want}) {
|
||||
return $gidcache{$want};
|
||||
}
|
||||
my $name=scalar getgrgid($want);
|
||||
return $gidcache{$want}=defined $name ? $name : $want;
|
||||
}
|
||||
chomp;
|
||||
my @stat=stat($_);
|
||||
my $mode = $stat[2];
|
||||
my $uid = $stat[4];
|
||||
my $gid = $stat[5];
|
||||
s/$q/$q"$q"$q/g; # escape single quotes
|
||||
s/^/$q/;
|
||||
s/$/$q/;
|
||||
if ($uid != $>) {
|
||||
printf "maybe chown $q%s$q %s\n", uidname($uid), $_;
|
||||
}
|
||||
if ($gid != $)) {
|
||||
printf "maybe chgrp $q%s$q %s\n", gidname($gid), $_;
|
||||
}
|
||||
printf "maybe chmod %04o %s\n", $mode & 07777, $_;
|
||||
'
|
||||
return $?
|
||||
else
|
||||
# fallback if perl isn't present
|
||||
euid=$(id -u)
|
||||
egid=$(id -g)
|
||||
q="'"
|
||||
while read x; do
|
||||
stat=$(stat -c "%f:%u:%g:%a:%U:%G" $x)
|
||||
IFS=":" read mode uid gid perm uname gname <<EOF
|
||||
$stat
|
||||
EOF
|
||||
x=$q$(echo $x | sed "s/$q/$q\"$q\"$q/")$q
|
||||
if [ $uid -ne $euid ]; then
|
||||
echo maybe chown "'$uname'" $x
|
||||
fi
|
||||
if [ $gid -ne $egid ]; then
|
||||
echo maybe chgrp "'$gname'" $x
|
||||
fi
|
||||
echo maybe chmod 0$perm $x
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$VCS" = git ] || [ "$VCS" = hg ] || [ "$VCS" = bzr ] || [ "$VCS" = darcs ]; then
|
||||
if [ -f .metadata ]; then
|
||||
# remove obsolete .metadata file
|
||||
# git allows fully deleting it at this point, other VCS
|
||||
# may not (the repo is locked for hg).
|
||||
if [ "$VCS" = git ]; then
|
||||
$VCS rm .metadata
|
||||
else
|
||||
rm -f .metadata
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "# Generated by etckeeper. Do not edit." > .etckeeper
|
||||
echo >> .etckeeper
|
||||
|
||||
# Make sure the file is not readable by others, since it can leak
|
||||
# information about contents of non-readable directories in /etc.
|
||||
chmod 700 .etckeeper
|
||||
|
||||
generate_metadata >> .etckeeper
|
||||
|
||||
# stage the file as part of the current commit
|
||||
if [ "$VCS" = git ]; then
|
||||
# this will do nothing if the metadata file is unchanged.
|
||||
git add .etckeeper
|
||||
fi
|
||||
# hg, bzr and darcs add not done, they will automatically
|
||||
# include the file in the current commit
|
||||
fi
|
||||
2
etckeeper/pre-commit.d/README
Normal file
2
etckeeper/pre-commit.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This is run by a git pre-commit hook before committing changes to the
|
||||
repository. This can be used for storing metadata, and for sanity checks.
|
||||
5
etckeeper/pre-install.d/10packagelist
Executable file
5
etckeeper/pre-install.d/10packagelist
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This list will be later used when committing.
|
||||
mkdir -p /var/cache/etckeeper/
|
||||
etckeeper list-installed > /var/cache/etckeeper/packagelist.pre-install
|
||||
etckeeper list-installed fmt > /var/cache/etckeeper/packagelist.fmt
|
||||
15
etckeeper/pre-install.d/50uncommitted-changes
Executable file
15
etckeeper/pre-install.d/50uncommitted-changes
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if etckeeper unclean; then
|
||||
if [ "$AVOID_COMMIT_BEFORE_INSTALL" = 1 ]; then
|
||||
echo "" >&2
|
||||
echo "** etckeeper detected uncommitted changes in /etc prior to $HIGHLEVEL_PACKAGE_MANAGER run" >&2
|
||||
echo "** Aborting $HIGHLEVEL_PACKAGE_MANAGER run. Manually commit and restart." >&2
|
||||
echo "" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! etckeeper commit "saving uncommitted changes in /etc prior to $HIGHLEVEL_PACKAGE_MANAGER run"; then
|
||||
echo "warning: etckeeper failed to commit changes in /etc using $VCS" >&2
|
||||
fi
|
||||
fi
|
||||
3
etckeeper/pre-install.d/README
Normal file
3
etckeeper/pre-install.d/README
Normal file
@@ -0,0 +1,3 @@
|
||||
Files in this directory are run before packages are installed, upgraded,
|
||||
etc. This is mostly used for sanity checks, ie, does /etc have any
|
||||
uncommitted changes?
|
||||
12
etckeeper/unclean.d/50test
Executable file
12
etckeeper/unclean.d/50test
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ]; then
|
||||
[ -d .git ] && [ -n "`git status --porcelain`" ]
|
||||
elif [ "$VCS" = hg ]; then
|
||||
[ -d .hg ] && ! hg status 2>&1 | wc -l | grep -q "^0$"
|
||||
elif [ "$VCS" = bzr ]; then
|
||||
[ -d .bzr ] && ! bzr version-info --custom --template="{clean}\n" | grep -q "^1$"
|
||||
elif [ "$VCS" = darcs ]; then
|
||||
[ -d _darcs ] && darcs whatsnew -l >/dev/null
|
||||
fi
|
||||
2
etckeeper/unclean.d/README
Normal file
2
etckeeper/unclean.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
Files in this directory are used to test if the working copy has
|
||||
uncommitted changes.
|
||||
20
etckeeper/uninit.d/01prompt
Executable file
20
etckeeper/uninit.d/01prompt
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$1" != "-f" ]; then
|
||||
echo "** Warning: This will DESTROY all recorded history for $ETCKEEPER_DIR,"
|
||||
echo "** including the $VCS repository."
|
||||
echo ""
|
||||
printf "Are you sure you want to do this? [yN] "
|
||||
read answer
|
||||
case "$answer" in
|
||||
[Yy]*)
|
||||
echo "Proceeding.."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Aborting etckeeper uninit."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
6
etckeeper/uninit.d/50remove-metadata
Executable file
6
etckeeper/uninit.d/50remove-metadata
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Files generated by etckeeper to store metadata the VCS cannot preserve.
|
||||
rm -f .etckeeper
|
||||
rm -f .metadata # only generated by old versions
|
||||
54
etckeeper/uninit.d/50vcs-uninit
Executable file
54
etckeeper/uninit.d/50vcs-uninit
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ]; then
|
||||
rm -rf .git
|
||||
file=.gitignore
|
||||
elif [ "$VCS" = hg ]; then
|
||||
rm -rf .hg
|
||||
file=.hgignore
|
||||
elif [ "$VCS" = bzr ]; then
|
||||
rm -rf .bzr
|
||||
file=.bzrignore
|
||||
elif [ "$VCS" = darcs ]; then
|
||||
rm -rf _darcs
|
||||
file=.darcsignore
|
||||
fi
|
||||
|
||||
managed_by_etckeeper="managed by etckeeper"
|
||||
|
||||
if ! grep -q "$managed_by_etckeeper" "$file"; then
|
||||
exit 0
|
||||
else
|
||||
realfile="$file"
|
||||
if command -v mktemp >/dev/null; then
|
||||
tempfile="mktemp"
|
||||
elif command -v tempfile >/dev/null; then
|
||||
tempfile="tempfile"
|
||||
else
|
||||
echo "etckeeper warning: can't find tempfile or mktemp" >&2
|
||||
exit 1
|
||||
fi
|
||||
file=$($tempfile)
|
||||
otherentries=
|
||||
skipping=
|
||||
while read -r line; do
|
||||
if echo "$line" | grep -q "$managed_by_etckeeper"; then
|
||||
if [ ! "$skipping" ]; then
|
||||
skipping=1
|
||||
else
|
||||
skipping=
|
||||
fi
|
||||
elif [ ! "$skipping" ]; then
|
||||
echo "$line" >> "$file"
|
||||
otherentries=1
|
||||
fi
|
||||
done <"$realfile"
|
||||
|
||||
if [ "$otherentries" ]; then
|
||||
mv -f "$file" "$realfile"
|
||||
else
|
||||
rm -f "$file"
|
||||
rm -f "$realfile"
|
||||
fi
|
||||
fi
|
||||
2
etckeeper/uninit.d/README
Normal file
2
etckeeper/uninit.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
Executable files in this directory are run to uninitialise the working
|
||||
directory, removing files added by `etckeeper init`.
|
||||
216
etckeeper/update-ignore.d/01update-ignore
Executable file
216
etckeeper/update-ignore.d/01update-ignore
Executable file
@@ -0,0 +1,216 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$VCS" = git ]; then
|
||||
dir=.git
|
||||
file=.gitignore
|
||||
elif [ "$VCS" = hg ]; then
|
||||
dir=.hg
|
||||
file=.hgignore
|
||||
elif [ "$VCS" = bzr ]; then
|
||||
dir=.bzr
|
||||
file=.bzrignore
|
||||
elif [ "$VCS" = darcs ]; then
|
||||
dir=_darcs
|
||||
file=.darcsignore
|
||||
else
|
||||
echo "etckeeper: unsupported VCS $VCS" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d "$dir" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
managed_by_etckeeper="managed by etckeeper"
|
||||
|
||||
nl() {
|
||||
echo >>"$file"
|
||||
}
|
||||
|
||||
comment() {
|
||||
comment="$1"
|
||||
echo "# $comment" >>"$file"
|
||||
}
|
||||
|
||||
ignore() {
|
||||
glob="$1"
|
||||
|
||||
case "$VCS" in
|
||||
git)
|
||||
# escape "#" in ignores, as otherwise it may
|
||||
# be considered a comment
|
||||
echo "$glob" | sed 's/#/\\#/g' >>"$file"
|
||||
;;
|
||||
bzr)
|
||||
echo "$glob" >>"$file"
|
||||
;;
|
||||
hg)
|
||||
# rather than converting the glob to a regexp, just
|
||||
# configure hg to use globs
|
||||
if [ -z "$hg_syntax_printed" ]; then
|
||||
comment "use glob syntax"
|
||||
echo "syntax: glob" >>"$file"
|
||||
nl
|
||||
hg_syntax_printed=1
|
||||
fi
|
||||
echo "$glob" | sed 's/#/\\#/g' >>"$file"
|
||||
;;
|
||||
darcs)
|
||||
# darcs doesn't understand globs, so we need to
|
||||
# translate them into regexs. Not a complete converter,
|
||||
# but suitable for given globs.
|
||||
if [ "${glob%\*}" != "$glob" ]; then
|
||||
glob="${glob%\*}"
|
||||
else
|
||||
glob="$glob"'($|/)'
|
||||
fi
|
||||
if [ "${glob#\*}" != "$glob" ]; then
|
||||
glob="${glob#\*}"
|
||||
else
|
||||
glob='(^|/)'"$glob"
|
||||
fi
|
||||
glob="$( printf %s $glob | sed -e 's/\./\\./g;s/\*/[^\/]*/g;s/\?/[^\/]/g' )"
|
||||
echo "$glob" >>"$file"
|
||||
esac
|
||||
}
|
||||
|
||||
writefile () {
|
||||
comment "begin section $managed_by_etckeeper (do not edit this section by hand)"
|
||||
nl
|
||||
|
||||
if [ "$VCS" = darcs ]; then
|
||||
darcs setpref boringfile .darcsignore
|
||||
fi
|
||||
|
||||
if [ "$LOWLEVEL_PACKAGE_MANAGER" = dpkg ]; then
|
||||
comment "new and old versions of conffiles, stored by dpkg"
|
||||
ignore "*.dpkg-*"
|
||||
comment "new and old versions of conffiles, stored by ucf"
|
||||
ignore "*.ucf-*"
|
||||
nl
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = "rpm" ]; then
|
||||
comment "new and old versions of conffiles, stored by apt/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"
|
||||
ignore "*.pacnew"
|
||||
ignore "*.pacorig"
|
||||
ignore "*.pacsave"
|
||||
nl
|
||||
elif [ "$LOWLEVEL_PACKAGE_MANAGER" = "apk" ]; then
|
||||
comment "new versions of conffiles, stored by apk"
|
||||
ignore "*.apk-new"
|
||||
nl
|
||||
fi
|
||||
|
||||
comment "old versions of files"
|
||||
ignore "*.old"
|
||||
# Not currently ignored as admins tend to rely on these files.
|
||||
#ignore "passwd-"
|
||||
#ignore "group-"
|
||||
#ignore "shadow-"
|
||||
#ignore "gshadow-"
|
||||
nl
|
||||
|
||||
comment "mount(8) records system state here, no need to store these"
|
||||
ignore blkid.tab
|
||||
ignore blkid.tab.old
|
||||
nl
|
||||
|
||||
comment "some other files in /etc that typically do not need to be tracked"
|
||||
ignore nologin
|
||||
ignore ld.so.cache
|
||||
ignore prelink.cache
|
||||
ignore mtab
|
||||
ignore mtab.fuselock
|
||||
ignore .pwd.lock
|
||||
ignore "*.LOCK"
|
||||
ignore network/run
|
||||
ignore adjtime
|
||||
ignore lvm/cache
|
||||
ignore lvm/archive
|
||||
ignore "X11/xdm/authdir/authfiles/*"
|
||||
ignore ntp.conf.dhcp
|
||||
ignore .initctl
|
||||
ignore "webmin/fsdump/*.status"
|
||||
ignore "webmin/webmin/oscache"
|
||||
ignore "apparmor.d/cache/*"
|
||||
ignore "service/*/supervise/*"
|
||||
ignore "service/*/log/supervise/*"
|
||||
ignore "sv/*/supervise/*"
|
||||
ignore "sv/*/log/supervise/*"
|
||||
ignore "*.elc"
|
||||
ignore "*.pyc"
|
||||
ignore "*.pyo"
|
||||
ignore "init.d/.depend.*"
|
||||
ignore "openvpn/openvpn-status.log"
|
||||
ignore "cups/subscriptions.conf"
|
||||
ignore "cups/subscriptions.conf.O"
|
||||
ignore "fake-hwclock.data"
|
||||
ignore "check_mk/logwatch.state"
|
||||
nl
|
||||
|
||||
comment "editor temp files"
|
||||
ignore "*~"
|
||||
ignore ".*.sw?"
|
||||
ignore ".sw?"
|
||||
ignore "#*#"
|
||||
ignore DEADJOE
|
||||
|
||||
nl
|
||||
comment "end section $managed_by_etckeeper"
|
||||
}
|
||||
|
||||
if [ -e "$file" ]; then
|
||||
if ! grep -q "$managed_by_etckeeper" "$file"; then
|
||||
if [ "$1" != "-a" ]; then
|
||||
echo "etckeeper: "$file" does not contain \"$managed_by_etckeeper\" comment; not updating"
|
||||
exit 1
|
||||
else
|
||||
echo "etckeeper: "$file" exists but does not contain \"$managed_by_etckeeper\" comment; updating"
|
||||
writefile
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
realfile="$file"
|
||||
if command -v mktemp >/dev/null; then
|
||||
tempfile="mktemp"
|
||||
elif command -v tempfile >/dev/null; then
|
||||
tempfile="tempfile"
|
||||
else
|
||||
echo "etckeeper warning: can't find tempfile or mktemp" >&2
|
||||
fi
|
||||
file=$($tempfile)
|
||||
|
||||
# preserve permissions and ownership
|
||||
cp -fp "$realfile" "$file"
|
||||
cat /dev/null >"$file"
|
||||
|
||||
(
|
||||
skipping=
|
||||
while read -r line; do
|
||||
if echo "$line" | grep -q "$managed_by_etckeeper"; then
|
||||
if [ ! "$skipping" ]; then
|
||||
skipping=1
|
||||
else
|
||||
skipping=
|
||||
writefile
|
||||
fi
|
||||
elif [ ! "$skipping" ]; then
|
||||
echo "$line" >> "$file"
|
||||
fi
|
||||
done
|
||||
if [ "$skipping" ]; then
|
||||
# reached end of file w/o ending block
|
||||
writefile
|
||||
fi
|
||||
) <"$realfile"
|
||||
|
||||
mv -f "$file" "$realfile"
|
||||
else
|
||||
writefile
|
||||
fi
|
||||
2
etckeeper/update-ignore.d/README
Normal file
2
etckeeper/update-ignore.d/README
Normal file
@@ -0,0 +1,2 @@
|
||||
Executable files in this directory are run to update the VCS ignore file,
|
||||
or create it if it does not exist.
|
||||
11
etckeeper/vcs.d/50vcs-cmd
Executable file
11
etckeeper/vcs.d/50vcs-cmd
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# check whether we can locate the vcs binary
|
||||
if [ -n "$VCS" ] && command -v "$VCS" > /dev/null; then
|
||||
# pass commands to the VCS application
|
||||
$VCS "$@"
|
||||
else
|
||||
echo "error: VCS ($VCS) not set or not in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user