git 次修订之间删除或修改的文件会自动从实例中删除

Files deleted or modified between git revisions are automatically getting deleted from instances

背景

我有一个由 Jenkins 触发的设置,具有以下 -

问题

我动态添加到 appspec.yml 文件的文件在 EC2 实例中得到 modified/added,正如我所料,但是,奇怪的是,要删除的文件也被删除了.我确认我没有逻辑删除那些写在我的 appspec 文件的 beforeInstall 挂钩中的文件。我的 beforeInstall 挂钩中只有一个 beforeInstall.sh 文件,没有其他挂钩。一旦我从 appspec 文件中删除该挂钩,删除就会停止。这是我的 appspec 文件 -

version: 0.0
os: linux
files:
{Pair of files dynamically generated}
  - source: config/deployment_config.json
    destination: /var/cake_1.2.0.6311-beta/deployment
permissions:
  - object: .
    pattern: "**"
    owner: sandeepan
    group: sandeepan
    mode: 777
    type:
      - file
hooks:
  BeforeInstall:
    - location: beforeInstall.sh

AWS Codedeploy 是否以某种方式与我的 git 托管(我使用的是 gitlab 而不是 github)通信并以某种方式获取有关要删除的文件的信息。

更新

我后来观察到,即使从 appspec.yml 文件中完全删除 hooks 部分,并从中央构建中删除相应的 .sh 文件,即 beforeInstall.sh、afterInstall.sh 等服务器(准备 S3 包的地方),因此 none 我的逻辑和对它的任何引用都将转到实例,要删除的文件仍会自动删除。

更新 2

今天发现git版本之间修改的文件也被自动删除 我有动态准备 appspec.yml 文件的逻辑。我修改为不添加一些文件。因此,有些文件存在于 git diff 中,但不存在于 appspec 文件中。结果,它们被删除但没有重新出现。 代码部署似乎在部署之前自动进行清理。我该如何停止? 我想添加我的自定义清理逻辑。

更新 3

beforeInstall.sh-

的内容
OUTPUT="$(w | grep -Po '(?<=load average: )[^,]*')"
rm -f /var/cake_1.2.0.6311-beta/deployment/deployment_config.json
path="$PWD"
php $path"/deployment-root/"$DEPLOYMENT_GROUP_ID"/"$DEPLOYMENT_ID"/deployment-archive/beforeInstall.php" ${OUTPUT}

/usr/local/nagios/libexec/check_logwarn -d /tmp/logwarn_hiphop_error /mnt/log/hiphop/error_`(date +'%Y%m%d')`.log #Just run a nagios check, so that counter corresponds to the line in the log corresponding to current timestamp/instant. Do not care about output. Note that we are not even looking for error hinting keywords (and hence not using -p because it needs to be used alongwith), because all we need to care about here is incrementing the nginx counter.

/usr/local/nagios/libexec/check_logwarn -d /tmp/logwarn_nginx_access /mnt/log/nginx/access_`(date +'%Y%m%d')`_`(date +'%H')`.log #Just run a nagios check, so that counter corresponds to the line in the log corresponding to current timestamp/instant. Acceptable http codes are also not being read from deployment_config.json.
printf "\n `date +%Y-%m-%d:%H:%M:%S` End of beforeInstall.sh"  >> /var/cake_1.2.0.6311-beta/deployment/deployment.log
exit 0

以及从上面调用的 beforeInstall.php 的内容 -

<?php 
file_put_contents('/var/cake_1.2.0.6311-beta/deployment/deployment.log', "\n ".date("Y-m-d H:i:s")." - Load print  ".$argv[1], FILE_APPEND);
$loadData = json_encode(array("load" => intval($argv[1]), "access_error_check_day" => date("Ymd"), "access_error_check_hour" => date("H"))); //error_check_day -> day when nagios error check was last run. We will accordingly check log files of days in between this day and the day of afterinstall (practically this can include a span of 2 days).

file_put_contents("/var/cake_1.2.0.6311-beta/deployment/serverLoad.json",$loadData); //separate from deployment_config.json. serverLoad.json is not copied from build server.
file_put_contents('/var/cake_1.2.0.6311-beta/deployment/deployment.log', "\n ".date("Y-m-d H:i:s")." loadData to config ".$loadData, FILE_APPEND);
?>

CodeDeploy 旨在部署应用程序,而不是简单地复制一组特定且不断不同的文件。

因此,在部署每个 'revision' 之前,CodeDeploy 将首先清理由 先前 修订部署的所有文件。让我解释一下。

所以,假设之前的应用部署上传了三个文件:

File A
File B
File C

然后下一次部署只包含这些文件:

File A
File C

Code Deploy 将首先清理 它在第一个修订版(A、B 和 C)上部署的 3 个文件,然后部署您的新修订版...它从不简单地上传对于预期的文件,它总是首先清理旧文件(通过查看之前的 'revision' 来确定)。这很重要,因为它揭示了您案例中看似神秘的行为。部署后的结果当然是:

File A
File C

现在,如果您手动将文件添加到 CodeDeploy 之外的组合中,这会变得很有趣。它只会清理它知道的东西,如果这个清理阶段没有删除它们,它也不会覆盖当前版本中的文件。当人们手动安装应用程序,然后尝试对同一文件夹执行 CodeDeploy 时,经常会出现这种情况……没有以前的修订,因此无需清理,然后它会尝试在现有文件之上复制并会出错。您通常希望目标文件夹为 'naked',以便您可以正确启动修订历史记录。

例如,在之前的场景中,如果您之前手动上传了文件 A、B 和 C,那么文件 A 和 B 的部署将会失败,因为它不知道先清理 A、B 和 C,然后它会在尝试覆盖文件 A 和 B 时出错。

一个文件(或文件夹)完全在部署之外...即不属于任何一个修订版,比如文件 D...将保持原样并在之前愉快地保留在那里并且部署后没有投诉。这对于放置数据文件和可能特定于部署但不一定是您不想不断重新部署的代码库的一部分的东西很有用。

现在,您当然可以使用钩子做很多有趣的事情,但感觉它不是适合手头工作的工具。这些挂钩旨在执行 stop/start 服务等操作,而不是管理文件复制管理,而文件复制管理是 CodeDeploy 应该为您做的事情的核心。

从应用规范中排除所有文件(即未指定文件)并简单地使用 BeforeInstall and/or AfterInstall 步骤来执行复制逻辑是一种可能适用于某些情况的方法。

无论如何,也许更好地了解 CodeDeploy 的运作方式可能会帮助您制定解决方案。我认为它没有特别好的记录。我的理解来自于我自己的观察和挣扎。