Bug 1331798 - Foreman hook host/managed/after_create runs before host has been created
Summary: Foreman hook host/managed/after_create runs before host has been created
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Satellite
Classification: Red Hat
Component: Hooks and Webhooks
Version: 6.1.8
Hardware: x86_64
OS: Linux
unspecified
low with 1 vote vote
Target Milestone: Unspecified
Assignee: Lukas Zapletal
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-04-29 14:22 UTC by Göran Törnqvist
Modified: 2020-08-13 08:27 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2017-06-15 10:42:05 UTC
Target Upstream Version:


Attachments (Terms of Use)

Description Göran Törnqvist 2016-04-29 14:22:07 UTC
Description of problem:

Im running a custom hook script in host/managed/after_create that does a:
hammer -u ****** -p ****** host set-parameter --host ${hostname} --name my_custom_parameter --value something
Problem is that I get a "Error: host not found" in return from hammer, the host doesn´t exist in foreman when the hook runs.

Tried forking out the command to a (sleep 10 ; hammer ...) & but forking doesn´t work for some reason in hooks.

Version-Release number of selected component (if applicable):
Satellite 6.1.8

How reproducible:
85% of the time. Sometimes the host exists and the parameter is added but mostly it doesn´t.

Steps to Reproduce:
1. Create hook /usr/share/foreman/config/hooks/host/managed/after_create/99_host_create.sh
2. Run hammer command as above in the script and log output to logfile

Actual results:
Logfile displays "Error: host not found"

Expected results:
Host exists when after_create is triggered.

Additional info:

Comment 2 Alexey Masolov 2017-06-13 23:53:04 UTC
Can reproduce the same problem with Satellite 6.2.9. 

# cat /usr/share/foreman/config/hooks/host/managed/after_create/10_fix_environment.sh 

#!/bin/sh

ACTION="$1"
FQDN="$2"

logger "foreman hook: executed $ACTION for $FQDN"

HOOK_OBJECT_FILE=$(mktemp -t foreman_hooks.XXXXXXXXXX)
cat > $HOOK_OBJECT_FILE

logger -t foreman-hook: $HOOK_OBJECT_FILE

ENV="` sed -e 's/^.*"environment_name":"\([^"]*\)".*/\1/g' <$HOOK_OBJECT_FILE`"
SOLLENV="` sed -e 's/^.*"hostgroup_title":"\([^"]*\)".*/\1/g' <$HOOK_OBJECT_FILE | awk -F/ '{ print $2}'`"
HOSTID="`sed -e 's/^.*"host":{[^{}]*"id":\([0-9]*\),.*$/\1/g' <$HOOK_OBJECT_FILE`"

logger -t foreman-hook: env $ENV sollenv $SOLLENV

if [ ! -z "$ENV" ]
then
    if [ "$ENV" != "$SOLLENV" ]
    then
       logger -t foreman-hook: "setting environment for $FQDN from $ENV to $SOLLENV"
       echo "hammer -u XXXXX -p XXXXX host update --id $HOSTID --environment $SOLLENV" 2>&1 | logger -t foreman-hook:
       hammer -u XXXXX -p XXXXX host update --id $HOSTID --environment $SOLLENV 2>&1 | logger -t foreman-hook:
    else
       logger "foreman-hook: $FQDN has correct Environment $ENV"
    fi
else
    which jgrep| logger -t foreman-hook:
fi


And the output is:
=================

May 19 13:32:07 satellite logger: foreman hook: executed after_create for host.example.com
May 19 13:32:07 satellite foreman-hook:: /tmp/foreman_hooks.RkPnann3v9
May 19 13:32:07 satellite foreman-hook:: env KT_Library_20160801_sles11_85 sollenv Library
May 19 13:32:07 satellite foreman-hook:: setting environment for host.example.com from KT_Library_20160801_sles11_85 to Library
May 19 13:32:09 satellite foreman-hook:: hammer -u XXXXX-p XXXXXhost update --id 2805 --environment Library
May 19 13:32:10 satellite foreman-hook:: Could not update the host:
May 19 13:32:10 satellite foreman-hook::  Resource host not found by id '2805'

Comment 3 Lukas Zapletal 2017-06-15 10:42:05 UTC
Hello, unfortunately you cannot use hammer command with hosts which are currently being processed by the hook itself. The database transaction is not yet complete. Foreman hooks executes the script in separate context, so it is not possible to directly modify the ActiveRecord objects yet. RFE is filed as https://github.com/theforeman/foreman_hooks/issues/4

You can experience random behaviour according to which worker process gets the request. Anyway, please avoid this completely. I suggest a workaround, create a separate script that will be spawned on the background and add sleep command there, or create a service or process that will do the required tasks and communicate the data via UNIX sockets.

Also an alternative is to create Foreman plugin in Ruby that can do anything you want during any transaction:

http://projects.theforeman.org/projects/foreman/wiki/How_to_Create_a_Plugin

Take foreman_hooks as an example but implement the required code as separate plugin. Then you can modify the host object as needed:

https://github.com/theforeman/foreman_hooks

Comment 4 hprakash 2017-07-14 06:33:24 UTC
@lzap, thanks for your input.


Note You need to log in before you can comment on or make changes to this bug.