Showing with 300 additions and 22 deletions.
  1. +2 −0 CHANGELOG
  2. +6 −5 Modulefile
  3. +0 −16 README
  4. +45 −0 README.md
  5. +50 −0 files/agent/r10k.ddl
  6. +56 −0 files/agent/r10k.rb
  7. +33 −0 files/application/jiminy.rb
  8. +22 −0 files/post-receive
  9. +25 −0 files/pre-commit
  10. +37 −0 manifests/mcollective.pp
  11. +21 −0 manifests/params.pp
  12. +3 −1 tests/init.pp
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
2013-06-12 - Zack Smith <zack@puppetlabs.com> - 0.0.1
* Initial Release
11 changes: 6 additions & 5 deletions Modulefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
name 'zack-r10k'
version '0.0.1'
source 'UNKNOWN'
source 'https://github.com/acidprime/r10k'
author 'zack'
license 'Apache License, Version 2.0'
summary 'UNKNOWN'
description 'UNKNOWN'
project_page 'UNKNOWN'
summary 'Dynamic environments with git & r10k'
description 'Module for setting up dynamic environments using r10k'
project_page 'https://github.com/acidprime/r10k'

## Add dependencies, if any:
# dependency 'username/name', '>= 1.2.0'
dependency 'puppetlabs/stdlib', '>= 4.1.0'
dependency 'puppetlabs/ruby', '>= 0.0.2'
16 changes: 0 additions & 16 deletions README

This file was deleted.

45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
r10k

This is the r10k setup module. It has a base class to configure r10k to
synchronize dynamic environments. You can be simply used by declaring it:

```puppet
class { 'r10k':
remote => 'git@github.com:someuser/puppet.git',
}
```

This will configure `/etc/r10k.yaml` and install the r10k gem after installing
ruby using the [puppetlabs/ruby](http://forge.puppetlabs.com/puppetlabs/ruby) module. It also has a few helper classes that do
some useful things. The following will add a `prerun_command` to puppet.conf.

```puppet
include r10k::prerun_command
```

The concept here is that this is declared on the puppet master(s) that have
been configured with r10k. This will cause r10k to synchronize before each
puppet run. Any errors synchronizing will be logged to the standard puppet run.

An mcollective agent is included in this module which can be used to do
on demand synchronization. This mcollective application and agent can be
installed on all masters using the following class

```puppet
include r10k::mcollective
```

Using mco you can then trigger mcollective to call r10k using

```shell
mco r10k synchronize
```

An example post-recieve hook is included in the files directory.
This hook can automatically cause code to synchronize on your
servers at time of push in git.


##Support

Please log tickets and issues at our [Projects site](https://github.com/acidprime/r10k/issues)
50 changes: 50 additions & 0 deletions files/agent/r10k.ddl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
metadata :name => "r10k",
:description => "Syncs modules using git ",
:author => "Zack Smith",
:license => "MIT",
:version => "1.0",
:url => "http://puppetlabs.com",
:timeout => 120

['push',
'pull',
'status'].each do |act|
action act, :description => "#{act.capitalize} " do
input :path,
:prompt => "Module path",
:description => "Operating on #{act}",
:type => :string,
:validation => '.',
:optional => false,
:maxlength => 256

output :path,
:description => "Operating on #{act}",
:display_as => "Path"
output :output,
:description => "Output from git",
:display_as => "Output"

output :error,
:description => "Error from git",
:display_as => "Errors"
display :always
end
end
['cache',
'environment',
'module',
'synchronize',
'sync'].each do |act|
action act, :description => "#{act.capitalize} " do
output :output,
:description => "Output from git",
:display_as => "Output"

output :error,
:description => "Error from git",
:display_as => "Errors"
display :always
end
end
# vim: set syntax=ruby:
56 changes: 56 additions & 0 deletions files/agent/r10k.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
module MCollective
module Agent
class R10k<RPC::Agent
metadata :name => 'r10k',
:description => 'Triggers git pulls on multi-master',
:author => 'Zack Smith',
:license => 'MIT',
:version => '1.0',
:url => 'http://puppetlabs.com',
:timeout => 120
['push',
'pull',
'status'].each do |act|
action act do
validate :path, :shellsafe
path = request[:path]
reply.fail "Path not found #{path}" unless File.exists?(path)
return unless reply.statuscode == 0
run_cmd act, path
reply[:path] = path
end
end
['cache',
'environment',
'module',
'synchronize',
'sync'].each do |act|
action act do
run_cmd act
end
end
private

def run_cmd(action,path=nil)
output = ''
git = ['/usr/bin/git']
r10k = ['/usr/bin/r10k']
case action
when 'push','pull','status'
cmd = git
cmd << 'push' if action == 'push'
cmd << 'pull' if action == 'pull'
cmd << 'status' if action == 'status'
reply[:status] = run(cmd, :stderr => :error, :stdout => :output, :chomp => true, :cwd => path )
when 'cache','environment','module','synchronize','sync'
cmd = r10k
cmd << 'cache' if action == 'cache'
cmd << 'synchronize' if action == 'synchronize' or action == 'sync'
cmd << 'environment' if action == 'environment'
cmd << 'module' if action == 'module'
reply[:status] = run(cmd, :stderr => :error, :stdout => :output, :chomp => true)
end
end
end
end
end
33 changes: 33 additions & 0 deletions files/application/jiminy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class MCollective::Application::R10k<MCollective::Application
def post_option_parser(configuration)
if ARGV.length >= 1
configuration[:command] = ARGV.shift
case configuration[:command]
when 'push','pull','status'
configuration[:path] = ARGV.shift || docs
end
else
docs
end
end

def docs
puts "Usage: #{$0} push | pull | status"
end

def main
mc = rpcclient("r10k", :chomp => true)
options = {:path => configuration[:path]} if ['push','pull','status'].include? configuration[:command]
mc.send(configuration[:command], options).each do |resp|
puts "#{resp[:sender]}:"
if resp[:statuscode] == 0
responses = resp[:data][:output]
puts responses if responses and ['push','pull','status'].include? configuration[:command]
else
puts resp[:statusmsg]
end
end
mc.disconnect
printrpcstats
end
end
22 changes: 22 additions & 0 deletions files/post-receive
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env ruby
# based on https://gist.github.com/rpflorence/478846
# figure out which repository this is
# assumes it's a bare repository
repository = /([^\/]*?)\.git$/.match(`pwd`.chomp)[1]

# get the stdins from git
stdins = []; stdins << $_ while gets

stdins.each do |str|
# parse the stdin string
arr = str.split
refs = arr[2].split('/')

# what we're really after
oldrev = arr[0] # SHA
newrev = arr[1] # SHA
ref_type = refs[1] # tags || heads (branch)
ref_name = refs[2] # develop, 1.4 etc.
system('mco r10k synchronize')
# now do whatcha gotta do
end
25 changes: 25 additions & 0 deletions files/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/ruby
# Based on an example from Jakov Sosic
def puppet_parser_validate(file)
system('puppet parser validate ' + file)
end

def puppet_lint(file)
system('puppet-lint --no-80chars-check ' + file)
end

#def puppet_erb_check(file)
# system('erb -x -T \'-\' ' + file + ' | ruby -c')
#end

# go through list of files, and call adequate checks
IO.popen('git diff --cached --name-only --diff-filter=ACM').readlines.each { |file|
file.sub!(/^\w (.*)\n/,'\1')
puts "Processing #{file}"
if file.match('.pp$')
exit 1 unless puppet_parser_validate file
exit 1 unless puppet_lint file
# elsif file.match('.erb$')
# exit 1 unless puppet_erb_check file
end
}
37 changes: 37 additions & 0 deletions manifests/mcollective.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class r10k::mcollective(
$agent_name = $r10k::params::mc_agent_name,
$app_name = $r10k::params::mc_app_name,
$agent_ddl = $r10k::params::mc_agent_ddl_name,
$agent_path = $r10k::params::mc_agent_path,
$app_path = $r10k::params::mc_application_path,
$mc_service = $r10k::params::mc_service_name,
) inherits r10k::params {
File {
ensure => present,
owner => 'root',
group => 'root',
mode => '0644',
notify => Service[$mc_service],
}
# Install the agent and its ddl file
file { "${app_path}/${app_name}" :
source => "puppet:///modules/${module_name}/application/${agent_name}",
}

file { "${agent_path}/${agent_ddl}" :
source => "puppet:///modules/${module_name}/agent/${agent_ddl}",
}

# Install the application file (all masters at the moment)
file { "${agent_path}/${agent_name}" :
source => "puppet:///modules/${module_name}/agent/${agent_name}",
require => File["${agent_path}/${agent_ddl}"],
}

# Create a service resource for the notification
if ! defined(Service[$mc_service]) {
service { $mc_service :
ensure => running,
}
}
}
21 changes: 21 additions & 0 deletions manifests/params.pp
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
class r10k::params
{
# Puppet Enterprise specific settings
if $::is_pe == 'true' {
# Mcollective configuration dynamic
$mc_service_name = 'pe-mcollective'
$plugins_dir = '/opt/puppet/libexec/mcollective/mcollective'
} else {
# Getting ready for FOSS support in this module

# Mcollective configuration dynamic
$mc_service_name = 'mcollective'
$plugins_dir = '/usr/libexec/mcollective/mcollective'
}

# r10k configuration
$r10k_config_file = '/etc/r10k.yaml'
$r10k_cache_dir = '/var/cache/r10k'
Expand All @@ -10,4 +23,12 @@
$git_server = $::settings::ca_server
$repo_path = '/var/repos'
$remote = "ssh://${git_server}${repo_path}/modules.git"

# Mcollective configuration static
$mc_agent_name = "${module_name}.rb"
$mc_agent_ddl_name = "${module_name}.ddl"
$mc_app_name = "${module_name}.rb"
$mc_agent_path = "${plugins_dir}/agent"
$mc_application_path = "${plugins_dir}/application"

}
4 changes: 3 additions & 1 deletion tests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
#
# Learn more about module testing here: http://docs.puppetlabs.com/guides/tests_smoke.html
#
include r10k
class { 'r10k':
remote => 'git@github.com:someuser/puppet.git',
}