Frage

Derzeit mein Rezept mit Attributen, dass Materie so strukturiert ist:

generasacodicetagpre.

Dadurch sorgen wir dafür, dass der anfängliche Start des Diensts über die Konfigurationsdateien verfügt, während jeder Ausführung den Dienst für den zweiten Execute-Block läuft, und wenn Änderungen von Konfigurationsdateien den Dienst neu starten, um die Änderungen abzuholen .

Wenn jedoch ein Kochlauf auftritt, wenn der Anfangszustand des Dienstes angehalten wird, (z. B. beim ersten Lauf oder wenn etwas schlechtes Geschehen) und Konfigurationsdateien (insbesondere auf dem ersten Lauf) geändert haben (insbesondere auf dem ersten Lauf, aber für andere möglich sind) Läuft), der erste Execute-Block führt dazu, dass der Dienst mit den korrekten Konfigurationsdateien bereits vorhanden war, und dann am Ende des Laufs, der Dienst wird unnötig neu gestartet. (Natürlich gehen Sie natürlich an, dass Ressourcen nach dem anfänglichen Start keinen Neustart des Dienstes verursachen)

Ändern der Zielaktion von Benachrichtigungen scheint nicht funktionsfähig zu sein (als sofortige Benachrichtigungen, die immer noch sofort erfolgen, erscheint, dann sind verzögerte Benachrichtigungen noch möglich), und außerdem wäre es nicht korrekt.

Wir können auch nicht das 2. Execute an den Dienst abonnieren, da er bereits läuft, wenn er bereits läuft, nicht erweckt.

Es ist sehr nit wählerisch, aber gibt es ein besseres Muster, das folgen kann, um Neustarts eines Dienstes für den ersten Lauf zu minimieren? Oder ein Mechanismus, um verzögerte Benachrichtigungen abzubrechen, wenn eine bestimmte Aktion eingenommen wird?

War es hilfreich?

Lösung

Ich habe eine Flag-Datei verwendet, um dies zu erreichen.

wie unten "APT-GET-Update" wird nicht einmal ausgeführt.

generasacodicetagpre.

Andere Tipps

Chef is designed to express configuration policy (system state), which is a slightly different thing than expressing a sequence of tasks to perform.

Fortunately since the DSL is ruby-based, resources can be redefined at runtime.

template "configfile1" do
  notifies :create, "ruby_block[restart_service1]", :immediately
end

template "configfile2" do
  notifies :create, "ruby_block[restart_service1]", :immediately
end

service "service1" do
  action [:enable, :start]
end

ruby_block "restart_service1" do
  block do

    r = resources(:service => "service1")
    a = Array.new(r.action)

    a << :restart unless a.include?(:restart)
    a.delete(:start) if a.include?(:restart)

    r.action(a)

  end
  action :nothing
end

This will rewrite the service resource to have "action [:enable, :restart]" instead of "action [:enable, :start]", if any of the template resources change state this run. So the ordering stays the same, and you only get one call through the service resource, instead of potentially three.

I am not sure, if will solve your problems with restarting the service too many times, but this structure seems more logical to me.

#Prepare everything to start the service
package 'packagename' do
  ...
end

template 'configfile1'
  notifies :restart, 'service[myservice]'
end
...
template 'configfileN'
  notifies :restart, 'service[myservice]'
end

execute "a command from package which generates and enables the init script" do
  notifies :restart, 'service[myservice]'
end

#Start the service
service 'myservice' do
  action :start
  supports :status => true, :start => true, :stop => true, :restart => true
end

#At this point service is surely running
execute "a command that should run once every time, that requires service to be running"

Every resource that changes the configuration file(s), should notify the service to restart.

I guess Chef is clever enough not to restart the service it just started. (I didn't pay attention to that before, but it seems to me that I would have, if there were unnecessary restarts)

Chef will only execute an action per resource, regardless of the number of times it's notified. It is, however, specific to each action. So if you send it a action :restart and also a action :start notification, then both will be executed in the order in which Chef encountered them. So what you are seeing with your code example is the initial :start notification from the execute block, followed by the template :restart notifications.

You should be able to avoid this by restructuring your recipe a bit and using subscribes if I'm following correctly.

package 'packagename' do
  ...
end

execute "a command from package which generates and enables the init script" do
  not_if File.exists?('/etc/init.d/myservice_script')
end

template 'configfile1'
  notifies :restart, 'service[myservice]'
end
...
template 'configfileN'
  notifies :restart, 'service[myservice]'
end

service 'myservice' do
  supports :status => true, :start => true, :stop => true, :restart => true
  subscribes :run, 'execute[a command from package which generates and enables the init script]', :immediately
  action :start
end

execute "a command that should run once every time, that requires service to be running"

First, we move the service resource to the bottom of the recipe so that it is only called once all other resources have been evaluated. Then we change the execute resource to subscribe to the :start action of the service[myservice] resource so that it will only ever execute this command when the :start action is called. We also add a bit of idempotency in there to make sure it doesn't just re-create the init script every run.

Finally, we add in all the templates with the normal notifications for service[myservice].

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top