aws / aws-codedeploy-agent

Host Agent for AWS CodeDeploy
https://aws.amazon.com/codedeploy
Apache License 2.0
329 stars 187 forks source link

Debian package installs systemd service to /etc/init.d instead of a valid unit directory #130

Open danielkza opened 7 years ago

danielkza commented 7 years ago

Just installed the agent on an Ubuntu 16.04 machine (version 1.0-1.1231 according to apt), and I noticed there is a /etc/init.d/codedeploy-agent.service file, which makes no sense, since there is already an init script there (/etc/init.d/codedeploy-agent), and the correct location for the systemd service is /lib/systemd/system or /etc/systemd/system.

I can confirm the issue by downloading the deb file and listing it`s files:

$ dpkg -c codedeploy-agent_1.0-1.1231_all.deb  | grep init.d
drwxr-xr-x awsadmin/amazon   0 2017-07-05 18:42 etc/init.d/
-rw-r--r-- awsadmin/amazon 460 2017-07-05 18:42 etc/init.d/codedeploy-agent.service
-rwxr-xr-x awsadmin/amazon 3022 2017-07-05 18:42 etc/init.d/codedeploy-agent
tangerini commented 7 years ago

That service file was placed in /etc/init.d for source control reason and is not meant to be part of the install process. When we build the RPM, we actually copy it to the correct systemd directory.

razvanphp commented 6 years ago

Are you sure?

(root@server) {~} # ls -al /etc/init.d/ |grep code
-rwxr-xr-x  1 2450 users 3022 Oct 18 21:01 codedeploy-agent
-rw-r--r--  1 2450 users  460 Oct 18 21:01 codedeploy-agent.service

PS: debian uses deb, not RPM.

Luzifer commented 6 years ago
(root@hostname) {~} # dpkg-query -L codedeploy-agent | grep "\.service"
/etc/init.d/codedeploy-agent.service

(root@hostname) {~} # systemctl status codedeploy-agent
● codedeploy-agent.service - LSB: AWS CodeDeploy Host Agent
   Loaded: loaded (/etc/init.d/codedeploy-agent; generated; vendor preset: enabled)
   Active: active (running) since Mon 2017-12-18 06:02:17 UTC; 2 weeks 1 days ago
     Docs: man:systemd-sysv-generator(8)
  Process: 24511 ExecStop=/etc/init.d/codedeploy-agent stop (code=exited, status=0/SUCCESS)
  Process: 24532 ExecStart=/etc/init.d/codedeploy-agent start (code=exited, status=0/SUCCESS)
    Tasks: 4 (limit: 4915)
   CGroup: /system.slice/codedeploy-agent.service
           ├─24549 codedeploy-agent: master 24549
           └─24553 codedeploy-agent: InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller of master 24549

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.

(root@hostname) {~} # apt-cache policy codedeploy-agent
codedeploy-agent:
  Installed: 1.0-1.1352
  Candidate: 1.0-1.1352
  Version table:
 *** 1.0-1.1352 100
        100 /var/lib/dpkg/status

Quite sure the codedeploy-agent package does not install the service-file properly.

eschulma commented 6 years ago

I am seeing the same thing on my Ubuntu instance.

eschulma commented 6 years ago

For what it's worth. I seem to have solved several problems by using systemctl to control codedeploy-agent rather than the service command. Maybe this misconfiguration may have contributed to the difference.

Luzifer commented 6 years ago

The file resides in a wrong location and is therefore not found by systemd. What happens on Debian based systems is that systemd has a sysv-init generator which automatically constructs a "wrapper" around /etc/init.d/... scripts. That's what is seen in my paste above: Systemd controls the init.d script instead of using its own service…

So yeah, it's currently possible to use systemd as long as the systemd-sysv-generator stays in place. When it's removed for whatever reason the whole thing will break.

eschulma commented 6 years ago

So is it safest for me to use systemctl or service? Systemctl seemed to work better. I am on Ubuntu BTW. Also I get a somewhat different status print out; in the Loaded section it is listed as "bad" but still loaded and running.

I did the AWS manual install, not through a package.

razvanphp commented 6 years ago

On a systemd system like yours, it does not matter which one you use, both of the commands are wrappers around systemd auto-generated init.d script.

To avoid problems, do this after the manual installation and systemd will be able to properly monitor the child process and restart it if it dies.

Hopefully the package will be fixed soon... looks like we are ignored here for such a small but important fix. CC @tangerini

sudo mv /etc/init.d/codedeploy-agent.service /lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart codedeploy-agent.service
eschulma commented 6 years ago

I don't know that AWS uses this forum too much. I recommend the developer forum; I have Premium Support and will mention it there, as I can confirm that no service files are in the right place even after running enable.

eschulma commented 6 years ago

OK, looks like you guys are right as making this fix prevents complaints about a non-native service. I have written a hopefully future-proof code snippet for the end of my user_data script, and tested it. The CodeDeploy service handles reboots correctly. Hope this helps someone else until AWS gets around to fixing it.

if [ -e "/etc/init.d/codedeploy-agent.service" ]; then
    if [ ! -e /lib/systemd/system/codedeploy-agent.service ] && [ ! -e /usr/lib/systemd/system/codedeploy-agent.service ]; then
        echo "Moving CodeDeploy service file to correct location."
        mv /etc/init.d/codedeploy-agent.service /lib/systemd/system/
    else 
        echo "CodeDeploy service file found in both /etc/init.d and a correct systemd directory -- removing /etc/init.d one"
        rm -f /etc/init.d/codedeploy-agent.service
    fi
    echo "CodeDeploy service file changed, reloading systemctl daemon."
    systemctl daemon-reload
    sleep 5s
else
    echo "CodeDeploy service file not in /etc/init.d, no change made."
fi
# Set to run at boot, then start (note --now does not always work)
systemctl enable codedeploy-agent
systemctl start codedeploy-agent
annamataws commented 6 years ago

eschulma, Thank you for posting your code snippet.

flyinprogrammer commented 5 years ago

so it looks like version 1.0-1.1597 is actually packaged with both..................

$ apt-cache policy codedeploy-agent
codedeploy-agent:
  Installed: 1.0-1.1597
  Candidate: 1.0-1.1597
  Version table:
 *** 1.0-1.1597 100
        100 /var/lib/dpkg/status
$ dpkg-query -L codedeploy-agent | grep '/etc/init.d/'
/etc/init.d/codedeploy-agent.service
/etc/init.d/codedeploy-agent

so i modified the snippet to be:

if [ -e "/etc/init.d/codedeploy-agent.service" ] || [ -e "/etc/init.d/codedeploy-agent" ]; then
    if [ ! -e /lib/systemd/system/codedeploy-agent.service ] && [ ! -e /usr/lib/systemd/system/codedeploy-agent.service ]; then
        echo "Moving CodeDeploy service file to correct location."
        sudo mv /etc/init.d/codedeploy-agent.service /lib/systemd/system/
        sudo rm -f /etc/init.d/codedeploy-agent
    else
        echo "CodeDeploy service file found in both /etc/init.d and a correct systemd directory -- removing /etc/init.d one"
        sudo rm -f /etc/init.d/codedeploy-agent.service
        sudo rm -f /etc/init.d/codedeploy-agent
    fi
    echo "CodeDeploy service file changed, reloading systemctl daemon."
    sudo systemctl daemon-reload
    sleep 5s
else
    echo "CodeDeploy service file not in /etc/init.d, no change made."
fi

and added sudo because i use this in a packer script.

mpdude commented 4 years ago

@yubangxi How do you package the .deb files – are the scripts available somewhere? If so, maybe we can help to sort this out.

philstrong commented 3 years ago

We'll pull this into the next sprint to investigate and share our packaging script here.