How to properly destroy a (content) host?

Hi,

foreman_expire_hosts is a plugin that allows users to define an expiration date for hosts. The hosts are then shut down as a first step and deleted after a grace period. To delete a host, I thought it was safe to just do a

@host.destroy!

As an issue on the plugin’s tracker suggests, that’s not enough for content hosts.

I had a look at katello’s code and saw, that the destroy actions from foreman core are overwritten all over the place.

What’s the recommended way to delete a host when Katello is in play?

ForemanTasks.sync_task(::Actions::Katello::Host::Destroy, @host)

Cheers,

Timo

Probably yes.

To give some context on why it was needed to be done in the first place:

the dynflow’s attempts to strictly separate the local database operations, that happen inside a transaction, and the external calls. The lifecycle is:

  1. in plan phase, do the local database stuff, and commit; rollbalck in case there is an error, which guarantees that there was no inconsistency introduced to remote systems
  2. once planning is finished, trigger the execution phase, that is managed by dynflow executor

This doesn’t play very nicely with the the activerecord callbacks. However, there is tooling in foreman-tasks to achieve just that, and I know about foreman_chef actually using this https://github.com/theforeman/foreman_chef/blob/master/app/models/foreman_chef/concerns/host_action_subject.rb

This way, on can call host.destroy and the corresponding task is triggered as part of it. One of the reasons I guess @katello folks went with overriding the host destroy controller behaviour to actually redirect to the task details?

One possible approach would be to actually provide a canned action in foreman-tasks around the destroying (similarly what foreman_chef does) and if desired in katello, still overriding the controllers (which should be probably discouraged anyway), but doing something like:

@host.destroy
redirect_to(foreman_tasks_task_path(@host.current_task.id)) # where we would expose the task triggered via the ActionTriggering there.

That would be at least the mid-term solution I would suggest. For the short term, you would probably need to check on presence of ::Actions::Katello::Host::Destroy and calling ForemanTasks.sync_task(::Actions::Katello::Host::Destroy, @host) in that case, which I agree is quite ugly way of doing things.

Host Destroy via the ui/api in katello is a syncronous task, so i don’t think that was it. Looking into our code history this goes back to 2014, so I dont’ think anyone is likely going to remember exactly why we did this. I think we should look into moving to the triggers that you mentioned are used in foreman_chef. We use them for host update and it tends to work well (as long as we’re careful).

1 Like

please don’t redirect to the tasks page, if you want to show a progress, then please have a customized progress vs send the user to a generic tasks page.

I would also think that its OK to report back and say host is scheduled for deletion and expect the user to still see the host while its being deleted.
if it failed, we can probably send a notification via the notification drawer.