如何使用 git 或其他 VCS 对应用程序运行时更改的服务器配置文件进行版本控制?

如何使用 git 或其他 VCS 对应用程序运行时更改的服务器配置文件进行版本控制?

我正在运行一个 Minecraft 服务器 (craftbukkit),还有其他几个管理员想要修改服务器配置文件。跟踪他们的所有更改对我来说很重要,因此 git 自然是一个不错的选择。

请注意,这个问题可能涉及很多情况,它并不是 Minecraft 所特有的。

关于使用 git 管理网站,有多个教程。最常见的解决方案似乎是使用接收后钩子对 Web 目录运行签出操作。但是,在我的情形下,这会带来一些问题。

首先,管理员需要编辑一些文件在运行时由服务器更改。我假设如果我将服务器目录本身放入存储库中,这会使 git 感到困惑。如果我没有记错的话,使用 post-receive checkout 解决方案,这个问题就不会那么严重(我仍在学习 git)。

我还需要将服务器所做的更改推送到存储库中,以便管理员可以将这些更改提取到本地存储库中。我见过使用通知等待但这些似乎都只考虑了单个文件更改。我的服务器有 50-80 个配置文件,我需要跟踪这些文件,并在服务器运行时更​​改它们时自动提交。处理这个问题的最佳方法是什么?

请注意,使用 git 不是必需的。我只是喜欢到目前为止使用过的东西。如果有更好的工具来完成这项工作,我愿意使用它,只要它易于使用。请注意,我的服务器管理员不是程序员,也不是 Linux 高级用户,因此用户友好性很有帮助。

我最初在 StackOverflow 上发布了此内容,但有人说它更适合在这里。

答案1

这不是一个完整的答案,但希望有一些有用的想法:

通知等待可以很好地处理多个文件,并且可以递归地在目录上设置监视点。例如,我可以运行:

inotifywait -m -r -e close_write /etc

编辑完成后得到如下日志/etc/passwd/etc/postfix/main.cf

/etc/ CLOSE_WRITE,CLOSE .passwd.swpx
/etc/ CLOSE_WRITE,CLOSE .passwd.swp
/etc/ CLOSE_WRITE,CLOSE 4913
/etc/ CLOSE_WRITE,CLOSE passwd
/etc/ CLOSE_WRITE,CLOSE .passwd.swp
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swx
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swp
/etc/postfix/ CLOSE_WRITE,CLOSE 4913
/etc/postfix/ CLOSE_WRITE,CLOSE main.cf
/etc/postfix/ CLOSE_WRITE,CLOSE .main.cf.swp

您可以非常轻松地将其编写成一个脚本,该脚本在每次close_write事件发生时将文件提交到本地存储库并将更改推送到远程服务器。

另请注意因克龙是一种用于自动化这种基于 inotify 的工作流程的巧妙工具(但不会对解决方案的性质产生实质性改变)。

如果您的管理员编辑的文件与服务器在运行时更新的文件相同,那么您将遇到困难。这意味着您必须在服务器上设置某种自动冲突解决机制,这必然会导致丢失一些信息(嗯,明显的损失,至少,您显然可以保留存储库中两个不同分支中相冲突的更改,但服务器只能看到一个分支)。

我不认为这个问题或解决方案的任何部分都是 git 独有的。在任何类型的分布式、异步同步共享文件维护中,您都会遇到这些问题。

答案2

在类似情况下,我所做的是将实时配置设为存储库(我倾向于使用 Bazaar),并编写一个 cronjob 来自动提交任何更改。将实时配置设为 VCS 存储库应该没有问题——唯一的区别是目录.git,在大多数情况下应该忽略它。cronjob 的间隔可以是您满意的任何粒度。对于我的情况,每小时一次已经足够了,但如果有必要,也可以每 5 分钟一次,甚至 1 分钟一次。

答案3

关于使用 git 管理网站,有多个教程。最常见的解决方案似乎是使用接收后钩子对 Web 目录运行签出操作。

对于配置文件,请查看etckeeper

Name       : etckeeper
Arch       : noarch
Version    : 0.63
Release    : 1.el5
Size       : 36 k
Repo       : epel
Summary    : Store /etc in a SCM system (git, mercurial, bzr or darcs)
URL        : http://kitenet.net/~joey/code/etckeeper/
License    : GPLv2+
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).
           : To use bzr as backend, please also install the etckeeper-bzr package.
           : 
           : To start using the package please read /usr/share/doc/etckeeper-0.63/README

首先,管理员需要编辑一些文件在运行时由服务器更改

没问题。

我还需要将服务器所做的更改推送到存储库中,以便管理员可以将这些更改提取到他们的本地存储库中。

默认情况下,etckeeper每天作为 cron 作业运行:

/etc/cron.daily/etckeeper

#!/bin/sh
set -e
if [ -x /usr/bin/etckeeper ] && [ -e /etc/etckeeper/etckeeper.conf ]; then
    . /etc/etckeeper/etckeeper.conf
    if [ "$AVOID_DAILY_AUTOCOMMITS" != "1" ]; then
        # avoid autocommit if an install run is in progress
        lockfile=/var/cache/etckeeper/packagelist.pre-install
        if [ -e "$pe" ] && [ -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
fi

如果您还想推送到远程仓库,请按如下方式编辑上述文件:

        if etckeeper unclean; then
            etckeeper commit "daily autocommit" >/dev/null
            cd /etc && git push origin master
        fi

如果每天甚至每分钟的间隔都不够,观察者更改后可以立即提交配置文件:

/etc/watcher.ini

[DEFAULT]
logfile=/tmp/watcher.log
pidfile=/tmp/watcher.pid
[job1]
watch=/etc
events=create,delete,write_close
recursive=true
autoadd=true
command=cd /etc && etckeeper commit "daily autocommit" >/dev/null && git push origin master

试一试。

相关内容