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

时间:2016-11-24 14:55:23

标签: git amazon-web-services jenkins aws-code-deploy

背景

我有一个由Jenkins触发的设置,其中包含以下内容 -

  • 要部署的文件是通过phing,通过与git服务器交谈并在所需的git版本之间获取git diff在单独的构建服务器中准备的,而不需要AWS代码部署(就我而言)认为)。 phins构建由Jenkins触发。
  • 我只是将要添加/修改的文件(基于修订版的git差异)动态添加到appspec.yml文件中。我只准备要添加/修改到路径/home/jenkins/deployment/cd_deploy/codebase/的文件,并在"使用自定义工作区"下指定路径/home/jenkins/deployment/cd_deploy/。选项"高级项目选项" Jenkins项目,它基本上是构建服务器中需要上传到S3存储桶的位置。 请注意,我需要删除两个git版本之间删除的实例中的文件。
  • 然后Jenkins触发AWS Codedeploy,其中包含有关我已配置的代码部署的应用程序名称和部署组的信息。

问题

我动态添加到appspec.yml文件的文件正在EC2实例中进行修改/添加,正如我所料,但奇怪的是,要删除的文件也会被删除。我验证了我没有逻辑删除我在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部分,并从中央构建服务器(其中准备了S3 bundle)中删除了相应的.sh文件,即beforeInstall.sh,afterInstall.sh等),以便我的逻辑和对它的任何引用都没有进入实例,要删除的文件仍然会被自动删除。

更新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);
?>

1 个答案:

答案 0 :(得分:2)

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

因此,在部署每个修订版之前,CodeDeploy将首先清除以前的版本部署的所有文件。让我解释一下。

所以,让我们说以前的应用部署上传了三个文件:

File A
File B
File C

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

File A
File C

代码部署将首先清理它在第一个修订版(A,B和C)上部署的3个文件,然后部署新修订版...它从不简单地上传预期的文件,它始终先清理旧文件(通过查看之前的版本&#39;确定)。这很重要,因为它揭示了你案件中看似神秘的行为。部署后的结果当然是:

File A
File C

现在,如果您已经手动将文件添加到CodeDeploy之外的混合中,那就很有趣了。它只会清理它所知道的东西,如果这个清理阶段没有删除它,它也不会覆盖当前版本中的文件。当人们手动安装一个应用程序,然后尝试将CodeDeploy写入同一个文件夹时,经常可以看到这种情况......没有以前的版本,所以没有什么可以清理,然后它试图复制到现有文件并将出错。您通常希望目标文件夹是“裸露的”。所以你可以正确地开始修改历史。

例如,在之前的方案中,如果您之前已手动上传文件A,B和C ,则部署文件A&amp; B会失败,因为它不知道首先清理A,B和C,然后它会在尝试覆盖文件A和B时出错。

一个文件(或文件夹)完全在外部部署...即不是任何一个版本的一部分,比如说文件D ...将不受影响,并且在部署之前和之后都保持愉快投诉。这对于放置数据文件以及可能特定于部署但不一定是您不希望不断重新部署的代码库的一部分非常有用。

现在,你可以使用钩子做很多有趣的事情,当然,这对于手头的工作来说感觉就像是错误的工具。钩子用于执行停止/启动服务等操作,而不是管理CodeDeploy应该为您做的核心的文件复制管理。

从应用程序规范中排除所有文件(即没有指定文件),只需使用BeforeInstall和/或AfterInstall步骤来执行复制逻辑,这种方法可能适用于某些场景。

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