AWS codedeploy 部署在 afterInstall 步骤尝试从 sh 文件调用 php 文件时抛出“[stderr] 无法打开输入文件”

AWS codedeploy deployment throwing "[stderr] Could not open input file" while trying to invoke a php file from the sh file at afterInstall step

我在 appspec 文件中定义了以下内容 -

hooks:
  AfterInstall:
    - location: afterInstall.sh 

以下是 afterInstall.sh 的内容(我试图从 sh 文件调用 php 文件)-

php afterInstall.php

文件 afterInstall.sh 和 afterInstall.php 在我上传到 S3 的 zip 存档中处于同一级别(最外层)-

appspec.yml
afterInstall.sh
afterInstall.php

我收到以下错误 -

Error Code         ScriptFailed
Script Name        afterInstall.sh
Message            Script at specified location: afterInstall.sh failed with exit code 1

Log Tail          LifecycleEvent - AfterInstall
                  Script - afterInstall.sh
                  [stderr]Could not open input file: afterInstall.php

我还尝试将以下内容添加到 apppsec 文件的权限部分 -

permissions:
  - object: .
    pattern: "**"
    owner: sandeepan
    group: sandeepan
    mode: 777
    type:
      - file

注意 - 我有使用 sandeepan 用户的部署实例的登录凭据。

我对权限部分的具体作用有点困惑。来自 http://docs.aws.amazon.com/codedeploy/latest/userguide/app-spec-ref-permissions.html

The permissions section specifies how special permissions, if any, should be applied to the files and directories/folders in the files section after they are copied to the instance.

我也尝试过将 owner/group 指定为 root/root 并针对 afterInstall 挂钩指定 runas: root,但仍然出现相同的错误。

更新

我还尝试在文件部分指定 afterInstall.php 文件,并确保其权限和所有权正确 -

  - source: afterInstall.php
    destination: /var/cake_1.2.0.6311-beta

在 /var/cake_1.2.0.6311-beta -

-rwxrwxr-x  1 sandeepan sandeepan   26 Aug  1 08:55 afterInstall.php

我不知道还应该做些什么来解决这个问题。

注意 - 如果我不从 afterInstall.sh[=52 调用 php 文件,我可以成功部署=]

  • 对象条目可以是目录或文件,当前设置为“.”匹配到 CodeDeploy 部署存档目录,而不是脚本复制到的目标。所以也许你可以尝试使用文件目标目录作为对象。

  • 并且由于 CodeDeploy 部署存档目录包含客户包中的所有文件。我不太确定你的文件目录,但如果部署存档目录中的所有对象都是目录,则可能可以将归档类型更改为目录。

文件部分类似于以下结构,此部分指定在部署的安装事件期间应复制到实例的文件的名称。

files: - source: source-file-location destination: destination-file-location

虽然挂钩部分看起来像以下结构,但 AppSpec 文件的挂钩部分包含 link 部署生命周期事件挂钩到一个或多个脚本的映射。如果事件挂钩不存在,则不会对该事件执行任何操作。仅当您将 运行 脚本作为部署的一部分时才需要此部分。

hooks: deployment-lifecycle-event-name - location: script-location timeout: timeout-in-seconds runas: user-name

错误的根本原因是php文件引用不正确。您的脚本假定当前工作目录是目标文件夹或部署存档文件夹。

这是一个合理的假设,但是这两个都不正确。在我的 Ubuntu 服务器上,CodeDeploy shell 调用的当前工作目录实际上是 /opt/codedeploy-agent。这解释了为什么您会收到 "Could not open input file" 错误。

由于您处于 afterInstall 生命周期挂钩中,因此您的所有文件都已存在于最终目标中。要解决此问题,请使用 afterInstall.sh:

destination: 指令中指定的路径
#!/bin/bash
php /var/cake_1.2.0.6311-beta/afterInstall.php

这将允许 php 找到正确的文件,并且您的部署将 运行 成功。

更新:

如果要运行 beforeInstall 挂钩中的文件,该文件必须已经存在于系统中,并且被/tools 等固定路径引用。

这可以通过以下方式之一完成:

  1. 使用 user-data 脚本在实例启动时下载脚本,或者
  2. 'Baking' 将脚本放入 AMI 映像本身,并从该映像启动。

无论哪种情况,beforeInstall 挂钩都可以从其固定路径调用脚本,例如 php /tools/beforeInstall.php.

在这些情况下,我更喜欢选项 1。我们使用这些类型的资产维护一个 S3 存储桶,然后在 S3 上维护这些资产,并在启动时下载到每个实例。任何更新都会推送到 S3,并在每次启动新实例时调用。