可以使Ansible取消配置写入静态文件夹修改时间吗



我正在使用Ansible为WordPress安装编写一个构建过程。目前它还没有应用程序级的构建系统,我选择了Ansible,这样它就可以与服务器构建脚本干净地集成,这样我只需按一下按钮就可以启动一个工作服务器。

我的大多数WordPress插件都安装了unarchive功能,指向官方WordPress.org安装服务器上的版本插件构建。我只遇到过其中一个问题,即它总是被标记为"已更改",即使文件完全相同。

在检查了ls -Rl前后的状态后,我注意到这个插件(WordPress HTTPS)是唯一一个使用内部子目录的插件,每次解压缩时,文件夹的修改时间都会缩短。

知道这是一个connectionlocal的项目构建脚本可能会很有用。因此,我想这意味着SSH没有被使用。

以下是我的战术手册片段:

- name: Install the W3 Total Cache plugin
unarchive: >
src=https://downloads.wordpress.org/plugin/w3-total-cache.0.9.4.1.zip
dest=wp-content/plugins
copy=no
- name: Install the WP DB Manager plugin
unarchive: >
src=https://downloads.wordpress.org/plugin/wp-dbmanager.2.78.1.zip
dest=wp-content/plugins
copy=no
# @todo Since this has internal sub-folders, need to work out
# how to preserve timestamps of the original folders rather than
# re-writing them, which forces Ansible to record a change of
# server state.
- name: Install the WordPress HTTPS plugin
unarchive: >
src=https://downloads.wordpress.org/plugin/wordpress-https.3.3.6.zip
dest=wp-content/plugins
copy=no

解决此问题的一种方法是在之前和之后使用ls -R,使用包含文件大小但不包含时间戳的选项,然后使用输出的md5sum。如果校验和发生变化,我可以将其标记为已更改。它可以工作,但不是很优雅(为了一致性,我想对所有插件都这样做)。

另一种方法是,如果插件文件已经存在,则放弃该任务,但当我将插件版本号添加到最新副本时,这会导致问题。

因此,理想情况下,我正在寻找一个切换到unarchive,表示我希望从zip文件而不是从剧本运行时获得文件夹修改时间。有可能吗?


更新:一位评论者询问文件内容是否可能发生任何变化。为了确定它们是否有,我编写了这个脚本,它为(1)所有文件内容和(2)所有文件/目录时间戳创建了一个校验和:

#!/bin/bash
# Save pwd and then change dir to root location
STARTDIR=`pwd`
cd `dirname $0`/../..
# Clear collation file
echo > /tmp/wp-checksum
# List all files recursively
find wp-content/plugins/wordpress-https/ -type f | while read file
do
#echo $file
cat $file >> /tmp/wp-checksum
done
# Get checksum of file contents
sha1sum /tmp/wp-checksum
# Get checksum of file sizes
ls -Rl wp-content/plugins/wordpress-https/ | sha1sum
# Go back to original dir
cd $STARTDIR

我把它作为我的剧本的一部分运行(使用标签隔离运行),并收到了这个:

PLAY [Set this playbook to run locally] ****************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [jonblog : Run checksum command] ******************************************
changed: [localhost]
TASK [jonblog : debug] *********************************************************
ok: [localhost] => {
"checksum_before.stdout_lines": [
"374fadc4df1578f78fd60b1be6758477c2c533fa  /tmp/wp-checksum", 
"10d66f7bdbbdd3af531d1b11a3db3059a5868838  -"
]
}
TASK [jonblog : Install the WordPress HTTPS plugin] ***************
changed: [localhost]
TASK [jonblog : Run checksum command] ******************************************
changed: [localhost]
TASK [jonblog : debug] *********************************************************
ok: [localhost] => {
"checksum_after.stdout_lines": [
"374fadc4df1578f78fd60b1be6758477c2c533fa  /tmp/wp-checksum", 
"719c9da94b525e723b1abe188ee9f5bbaf121f3f  -"
]
}
PLAY RECAP *********************************************************************
localhost                  : ok=6    changed=3    unreachable=0    failed=0   

调试行反映文件内容的校验和哈希(这是相同的),然后是文件结构的ls -Rl的校验和散列(这已经改变)。这与我之前的手动发现一致,即目录校验和正在发生变化。

那么,我下一步该怎么做才能找到文件夹修改时间错误地将此操作标记为已更改的原因?

您可能希望使用unarchive模块的creates选项,而不是每次覆盖所有文件并找到保持相同修改日期时间的方法。

正如您可能已经知道的那样,这条消息会告诉Ansible,任务将创建一个特定的文件/文件夹。因此,如果该文件/文件夹已存在,则下次任务将不会再次运行。

请参阅http://docs.ansible.com/ansible/unarchive_module.html#options

我的解决方案是修改校验和脚本,并使其成为Ansible进程的永久特性。当Ansible应该为我做的时候,我自己做校验和感觉有点麻烦,但它有效。

最受欢迎的是,新的答案可以解释我做错了什么,或者新版的Ansible可以解决问题。

如果我有时间的话,我会向Ansible团队提出这个问题。然而,当我在繁忙的追踪器上发现bug时,我有时确实会想知道付出/回报的比例——我已经有一件物品没有完成了,它已经等了一段时间了,我也选择了解决这个问题。

更新(18个月后)

这个Ansible构建系统从未投入使用。感觉我总是在做一些事情。最近,当我决定需要将我的博客转移到另一台服务器时,我终于将其Dockeris。这花了几个星期的时间(因为在真正的WordPress安装中需要考虑的事情太多了),但总的来说,我发现这个过程比使用编排工具要好得多。

最新更新