Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Various small refactors:

 - use compound filters in the filter statements
 - add a disable lock file that prevents the agent from activating
 - add a data plugin that can retrieve the lock and disable status
 - use the data plugins in example config to correctly discover nodes
  • Loading branch information...
commit a8d6f9ed788b9be05d39abcee1ad252b5ed8ac9f 1 parent 54c7e0c
R.I.Pienaar authored
8 README.markdown
View
@@ -23,7 +23,6 @@ Each node more or less go through the following steps given the config file:
sign_node_csr: true
puppet_bootstrap_stage: true
puppet_final_run: true
- unlock: true
notify: true
master:
criteria:
@@ -54,7 +53,7 @@ Each node more or less go through the following steps given the config file:
1. Signs the certificate on all masters
1. Does an initial puppet run with the 'bootstrap_puppet' action
1. Does a 2nd puppet run via 'run_puppet' action. This should remove the provision agent from the node
- 1. Removes the lock file on the node
+ 1. Disable the agent preventing it from being discovered in future
1. Notifies my iPhone via boxcar
To do this we re-use a lot of existing agents:
@@ -68,13 +67,16 @@ Customizing
-----------
The basic flow is probably generic enough for most bootstrapping scenarios, cloud or non cloud, the specifics
-of the process should be captured in your agent. There's a sample agent in the agent subdir.
+of the process should be captured in your agent. There's a sample agent in the agent subdir. You will need
+to customise the agent for your specific scenario.
You can enable and disable individual steps that doesn't fit your needs in the steps section of the config file
Changelog
---------
+- 2012/11/09 - Add a data plugin that reports locking and disabled status
+- 2012/11/09 - Add a disable lock file
- 2011/02/04 - Improved error handling
- 2011/02/04 - Make the facts used to determine ip address connfigurable
- 2011/02/04 - Log backtraces when run in debug mode
26 agent/provision.ddl
View
@@ -1,10 +1,10 @@
-metadata :name => "Server Provisioning Agent",
- :description => "Agent to assist in provisioning new servers",
- :author => "R.I.Pienaar",
- :license => "Apache 2.0",
- :version => "1.1",
- :url => "http://mcollective-plugins.googlecode.com/",
- :timeout => 360
+metadata :name => "provision",
+ :description => "Agent to assist in provisioning new servers",
+ :author => "R.I.Pienaar",
+ :license => "Apache 2.0",
+ :version => "1.1",
+ :url => "http://mcollective-plugins.googlecode.com/",
+ :timeout => 360
action "set_puppet_host", :description => "Update /etc/hosts with the master IP" do
@@ -61,6 +61,18 @@ action "lock_deploy", :description => "Lock the deploy so new ones can not be st
:display_as => "Lock file"
end
+action "disable_provisioner", :description => "Completely disable the provisioner" do
+ output :disablefile,
+ :description => "The file that got created",
+ :display_as => "Lock file"
+end
+
+action "is_disabled", :description => "Determine if the install is currently disabled" do
+ output :disabled,
+ :description => "Is the install disabled",
+ :display_as => "Disabled"
+end
+
action "is_locked", :description => "Determine if the install is currently locked" do
output :locked,
:description => "Is the install locked",
28 agent/provision.rb
View
@@ -1,15 +1,20 @@
module MCollective
module Agent
class Provision<RPC::Agent
+ activate_when do
+ !File.exist?(Config.instance.pluginconf.fetch("provision.disablefile", "/etc/mcollective/provisioner.disable"))
+ end
+
def startup_hook
config = Config.instance
certname = PluginManager["facts_plugin"].get_fact("fqdn")
certname = config.identity unless certname
- @puppetcert = config.pluginconf["provision.certfile"] || "/var/lib/puppet/ssl/certs/#{certname}.pem"
- @lockfile = config.pluginconf["provision.lockfile"] || "/tmp/mcollective_provisioner_lock"
- @puppetd = config.pluginconf["provision.puppetd"] || "/usr/sbin/puppetd"
+ @puppetcert = config.pluginconf.fetch("provision.certfile", "/var/lib/puppet/ssl/certs/#{certname}.pem")
+ @lockfile = config.pluginconf.fetch("provision.lockfile", "/etc/mcollective/provisioner.lock")
+ @disablefile = config.pluginconf.fetch("provision.disablefile", "/etc/mcollective/provisioner.disable")
+ @puppetd = config.pluginconf.fetch("provision.puppetd", "/usr/sbin/puppetd")
end
action "set_puppet_host" do
@@ -78,11 +83,28 @@ def startup_hook
reply.fail! "Failed to unlock the install" if locked?
end
+ action "disable_provisioner" do
+ reply.fail! "Already disabled" if disabled?
+
+ File.open(@disablefile, "w") {|f| f.puts Time.now}
+ reply[:disablefile] = @disablefile
+
+ reply.fail! "Failed to disable the provisioner" unless disabled?
+ end
+
+ action "is_disabled" do
+ reply[:disabled] = disabled?
+ end
+
private
def has_cert?
File.exist?(@puppetcert)
end
+ def disabled?
+ File.exist?(@disablefile)
+ end
+
def locked?
File.exist?(@lockfile)
end
19 data/provision_data.ddl
View
@@ -0,0 +1,19 @@
+metadata :name => "provision",
+ :description => "Information about the server provisioner",
+ :author => "R.I.Pienaar",
+ :license => "Apache 2.0",
+ :version => "1.1",
+ :url => "http://mcollective-plugins.googlecode.com/",
+ :timeout => 1
+
+dataquery :description => "Provisioner Status" do
+ output :locked,
+ :description => "Is the provisioner currently locked",
+ :display_as => "Locked",
+ :default => true
+
+ output :disabled,
+ :description => "Is the provisioner currently disabled",
+ :display_as => "Disabled",
+ :default => true
+end
22 data/provision_data.rb
View
@@ -0,0 +1,22 @@
+module MCollective
+ module Data
+ class Provision_data<Base
+ activate_when do
+ !File.exist?(Config.instance.pluginconf.fetch("provision.disablefile", "/etc/mcollective/provisioner.disable"))
+ end
+
+ query do |q|
+ result[:locked] = locked?
+ result[:disabled] = disabled?
+ end
+
+ def disabled?
+ File.exist?(Config.instance.pluginconf.fetch("provision.disablefile", "/etc/mcollective/provisioner.disable"))
+ end
+
+ def locked?
+ File.exist?(Config.instance.pluginconf.fetch("provision.lockfile", "/etc/mcollective/provisioner.lock"))
+ end
+ end
+ end
+end
3  etc/provisioner.yaml
View
@@ -10,7 +10,6 @@ steps:
sign_node_csr: true
puppet_bootstrap_stage: true
puppet_final_run: true
- unlock: true
notify: false
master:
criteria:
@@ -20,7 +19,7 @@ master:
agent: puppetca
ipaddress_fact: ipaddress
target:
- filter: ""
+ filter: "provision().disabled=false and provision().locked=false"
agent: provision
ipaddress_fact: ipaddress
notify:
3  etc/provisioner.yaml.dist
View
@@ -10,7 +10,6 @@ steps:
sign_node_csr: false
puppet_bootstrap_stage: false
puppet_final_run: false
- unlock: false
notify: false
master:
criteria:
@@ -20,7 +19,7 @@ master:
agent: puppetca
ipaddress_fact: ipaddress
target:
- filter: ""
+ filter: "provision().disabled=false and provision().locked=false"
agent: provision
ipaddress_fact: ipaddress
notify:
5 lib/mcprovision/node.rb
View
@@ -11,6 +11,11 @@ def initialize(hostname, config, agent)
@inventory = fetch_inventory
end
+ def disable
+ MCProvision.info("Creating disable lock file on node")
+ request("disable_provisioner")
+ end
+
def lock
MCProvision.info("Creating lock file on node")
request("lock_deploy")
12 lib/mcprovision/runner.rb
View
@@ -55,7 +55,7 @@ def run
# - signs it on all masters
# - call puppet_bootstrap_stage which could run a small bootstrap environment client
# - call puppet_final_run which would do a normal puppet run, this steps block till completed
- # - deletes the lock file
+ # - disables the provisioner
# - sends a notification to administrators
def provision(node)
node_inventory = node.inventory
@@ -91,7 +91,7 @@ def provision(node)
node.bootstrap if @config.settings["steps"]["puppet_bootstrap_stage"]
node.run_puppet if @config.settings["steps"]["puppet_final_run"]
- node.unlock if @config.settings["steps"]["unlock"]
+ node.disable
@notifier.notify("Provisioned #{node.hostname} against #{chosen_master.hostname}", "New Node") if @config.settings["steps"]["notify"]
end
@@ -102,6 +102,9 @@ def provision(node)
# till we find a match, else return the first one.
def pick_master_from(facts, node)
masters = @master.find_all
+
+ raise "No masters found" if masters.empty?
+
chosen_master = masters.first
master_inventories = {}
@@ -132,11 +135,6 @@ def pick_master_from(facts, node)
rescue
end
- unless chosen_master
- chosen_master = masters.shuffle.first.hostname
- MCProvision.info("Picking #{chosen_master} for puppetmaster based on random selection after no masters matched facts")
- end
-
raise "Could not find any masters" if chosen_master.nil?
return [chosen_master, master_inventories[chosen_master.hostname]]
12 lib/mcprovision/util.rb
View
@@ -1,16 +1,8 @@
module MCProvision::Util
- # Parses a -W style filter and return a std filter option
+ # Parses a -S style filter and return a std filter option
def self.parse_filter(agent, filter)
result = MCollective::Util.empty_filter
-
- filter.split(" ").each do |f|
- if f =~ /.+?=.+/
- result["fact"] << MCollective::Util.parse_fact_string(f)
- else
- result["cf_class"] << f
- end
- end
-
+ result["compound"] << MCollective::Matcher.create_compound_callstack(filter) if filter.nil? || filter == ""
result["agent"] << agent
result
Please sign in to comment.
Something went wrong with that request. Please try again.