require 'open-uri' require 'socket' require 'yaml' class Runpuppet def self.with_lock(lock_file) recently_locked = (File.exists?(lock_file) and File.mtime(lock_file) > Time.now - 15*60) if recently_locked puts "can not run, lockfile #{lock_file} exists" else begin `touch #{lock_file}` yield ensure `rm #{lock_file}` end end end # simplified copy of rake`s sh def self.sh(cmd) puts cmd IO.popen(cmd) do |pipe| while str = pipe.gets puts str end end $?.success? end def self.get(path) path += (path.include?('?') ? '&' : '?') path += "hostname=#{Socket.gethostname}&ip=#{Config.local_ip}" open(Config.puppet_controller_url + path, Config.puppet_controller_auth) rescue puts "WARNING: no connection to puppet controller!" end def self.run(options={}) with_lock(Config.lock_file) do time = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S") todo, branch = get("/puppet/run").read.split('-') rescue [] if todo == 'run' or !options[:try] # try allows not running get '/puppet/status?status=started' branch ||= Config.default_branch cmd = Config.command.gsub('@@branch@@', branch) puts "#{time}: run #{branch}" if sh(cmd) get '/puppet/status?status=finished' else get '/puppet/status?status=error' exit 2 end else puts "#{time}: nothing to do" end end end class Config def self.config home = File.expand_path('~') ["#{home}/.runpuppet.yml", '/etc/runpuppet.yml'].each do |file| return YAML.load(File.read(file)) if File.exist?(file) end raise "No runpuppet.yml found in /etc or #{home}" end def self.puppet_controller_url config['puppet_controller_url'].sub(%r{/$},'') end def self.puppet_controller_auth extract_auth_from_url!(config['puppet_controller_url']) end def self.extract_auth_from_url!(url) url.sub!(%r{//(.*?):(.*?)@}, '//') auth = [$1, $2].compact auth.empty? ? nil : auth end def self.lock_file config['lock_file'] || '/tmp/runpuppet.lock' end def self.command config['command'] || "cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && puppet -v --debug --logdest console --modulepath /etc/puppet/repo/modules /etc/puppet/repo/manifests/site.pp" end def self.default_branch config['defaulf_branch'] || 'master' end def self.local_ip %x(ifconfig)[/192.168.\d+.\d+/] || config['local_ip'] end end end