0

I have the following defined in the appspec file -

hooks:
  AfterInstall:
    - location: afterInstall.sh 

Following is the content of afterInstall.sh (I am trying to invoke a php file from the sh file) -

php afterInstall.php

Both the files afterInstall.sh and afterInstall.php are at the same level (outermost level) in the zip archive that I am uploading to S3 -

appspec.yml
afterInstall.sh
afterInstall.php

I am getting the following error -

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

I also tried by adding the following to the permissions section of the apppsec file -

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

Note - I have the login credentials of the deployment instances using the sandeepan user.

I am a bit confused with what exactly the permissions section does. From 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.

I also tried by specifying owner/group as root/root and runas: root against the afterInstall hook, but still getting the same error.

Update

I also tried by specifying the afterInstall.php file in the files section, and ensuring its permission and ownerships are correct -

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

At /var/cake_1.2.0.6311-beta -

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

I have no other clue what else should be done to fix this.

Note - I am able to deploy successfully if I do not call a php file from the afterInstall.sh

Sandeepan Nath
  • 9,966
  • 17
  • 86
  • 144

2 Answers2

3

The root cause of the error is that the php file reference is incorrect. Your script assumes that the current working directory is the the destination folder, or the deployment archive folder.

This is a reasonable assumption, however neither of these is correct. On my Ubuntu server, the current working directory of the CodeDeploy shell invocation is actually /opt/codedeploy-agent. This explains why you get the "Could not open input file" error.

Since you are in the afterInstall lifecycle hook, all your files already exist in the final destination. To solve the problem, use the path specified in the destination: directive in your afterInstall.sh:

#!/bin/bash
php /var/cake_1.2.0.6311-beta/afterInstall.php

This will allow php to locate the correct file, and you deployment will run successfully.

Update:

If you want to run a file in the beforeInstall hook, the file must already exist on the system, and be referenced by a fixed path such as /tools.

This can be accomplished by one of the following:

  1. Use a user-data script to download the script at instance launch time, or
  2. 'Baking' the script into the AMI image itself, and launching from that image.

In either case, the beforeInstall hook can then call the script from its fixed path, eg php /tools/beforeInstall.php.

I prefer option 1 in these cases. We maintain an S3 bucket with these type of assets, which are then maintained on S3, and downloaded to each instance at launch time. Any updates are pushed to S3, and are called for each new instance launch.

Rodrigo Murillo
  • 13,080
  • 2
  • 29
  • 50
  • Perfect, this solves the issue. I don't know how I could not succeed by specifying the php file in the destination directory earlier. This is sorted now. But, how do I fix the same issue in case of beforeInstall step too (run a beforeInstall.php from beforeInstall.sh). I am getting the same error there too (could not open file). Mentioning the beforeInstall.php file in files section, to copy it won't work because file copying does not happen while the beforeInstall step runs. Any pointers? – Sandeepan Nath Aug 02 '16 at 07:36
  • Good to hear. Please see my update above for handling `beforeInstall` hooks. – Rodrigo Murillo Aug 02 '16 at 15:26
  • Perfect. Although I did not try with a script yet, which will download the beforeInstall.php script from S3, having the file at a fixed location in the instances worked for me. Thanks a lot for such clear explanations. – Sandeepan Nath Aug 03 '16 at 10:33
  • Please see if you could also answer this - http://stackoverflow.com/questions/38740298/jenkins-triggered-code-deploy-is-failing-at-applicationstop-step-even-though-sam – Sandeepan Nath Aug 03 '16 at 14:23
0
  • The object entry can be an directory or file, current setting "." matches to the CodeDeploy deployment archive directory not the destination where the scripts were copied to. So probably you can try to use the file destination directory as the object.

  • And since the CodeDeploy deployment archive directory contains all the files from customer's bundle. I'm not quite sure about your file directory, but if all the objects inside the deployment archive directory are directories, probably the type filed can be changed to directory.

The file section looks like the following structure, and this section specifies the names of files that should be copied to the instance during the deployment's Install event.

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

While the hook section looks like the following structure, The hooks section of the AppSpec file contains mappings that link deployment lifecycle event hooks to one or more scripts. If an event hook is not present, then no operation is executed for that event. This section is required only if you will be running scripts as part of the deployment.

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

binbinlu
  • 416
  • 2
  • 5
  • Ok. I will then try by specifying the destination (the full qualified path), instead of the "."? However, why would someone need to specify the deployment archive directory then (using ".")? Also, I was initially trying without mentioning the permissions section, in which case also, I was getting the same "could not open input file" error. Any pointers to fix that? – Sandeepan Nath Jul 31 '16 at 08:44
  • My file structure is such that all the script files (specified in the hooks) are located at the root level, where appspec.yml file it. All the code is present inside a /codebase directory. Let me know if you need any more details. – Sandeepan Nath Aug 01 '16 at 07:28
  • I am confused all over again. Do you mean my hooks script files (beforeInstall, afterInstall etc ) need to be run from the destination folder, i.e. where my application is deployed? – Sandeepan Nath Aug 01 '16 at 07:39
  • Also, please check the question's update where I have mentioned what I found after moving the afterInstall.php file to the deployment directory, so as to be able to check its permission/ownership. – Sandeepan Nath Aug 01 '16 at 13:21
  • Could you make sure sandeepan has permission to the script invoked by afterInstall.sh? All scripts ran by host agent need to owned by the user specified in the appspec – binbinlu Aug 02 '16 at 00:48