runpuppet 1.0.0.rc1 → 1.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.rdoc +23 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/runpuppet +9 -7
- data/lib/ext/core.rb +8 -0
- data/lib/runpuppet.rb +21 -131
- data/lib/runpuppet/agent.rb +77 -0
- data/lib/runpuppet/client.rb +76 -0
- data/lib/runpuppet/config.rb +94 -0
- data/lib/runpuppet/logger.rb +6 -0
- data/runpuppet.gemspec +16 -1
- data/sh/c +1 -0
- data/sh/console.rb +14 -0
- data/sh/test +1 -0
- data/test/agent_test.rb +49 -0
- data/test/binary_test.rb +7 -0
- data/test/client_test.rb +37 -0
- data/test/config_test.rb +89 -0
- data/test/fixtures/runpuppet.yml +7 -0
- data/test/fixtures/shell/arp_eth0.txt +2 -0
- data/test/fixtures/shell/ip_addr_list_eth0.txt +5 -0
- data/test/helper.rb +32 -0
- metadata +18 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -11,6 +11,28 @@ cat /etc/runpuppet.yml:
|
|
11
11
|
lock_file: /tmp/runpuppet.lock
|
12
12
|
|
13
13
|
|
14
|
+
### Run tests
|
15
|
+
|
16
|
+
sh/test
|
17
|
+
|
18
|
+
|
19
|
+
#### Start console
|
20
|
+
|
21
|
+
sh/c
|
22
|
+
|
23
|
+
#### Playing in console
|
24
|
+
|
25
|
+
@ctx = Runpuppet.setup_context({})
|
26
|
+
|
27
|
+
# client
|
28
|
+
@ctx.client
|
29
|
+
|
30
|
+
# config
|
31
|
+
@ctx.config
|
32
|
+
|
33
|
+
# agent ### HTTP agent
|
34
|
+
@ctx.agent
|
35
|
+
|
14
36
|
|
15
37
|
|
16
38
|
This is the companion for our puppet_controller, a light-weight web-service to coordinate local puppet runs on servers.
|
@@ -27,6 +49,6 @@ This is the companion for our puppet_controller, a light-weight web-service to c
|
|
27
49
|
|
28
50
|
== Copyright
|
29
51
|
|
30
|
-
Copyright (c)
|
52
|
+
Copyright (c) 2012 Roman Heinrich. See LICENSE.txt for
|
31
53
|
further details.
|
32
54
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0.rc2
|
data/bin/runpuppet
CHANGED
@@ -20,17 +20,19 @@ BANNER
|
|
20
20
|
|
21
21
|
opts.on("-h", "--help","Show this.") { puts opts; exit }
|
22
22
|
opts.on("--readme", 'Show Readme'){ puts File.read(File.join(File.dirname(__FILE__), '..', 'README.rdoc')); exit }
|
23
|
-
opts.on('
|
24
|
-
opts.on('--try','Runs only if selected on puppet_controller'){ options[:try] = true }
|
25
|
-
opts.on('-f', '--facts','Report facts'){ options[:facts] = true }
|
26
|
-
opts.on('--verbose','Verbose
|
23
|
+
opts.on('--version', 'Show Version'){ puts Runpuppet::VERSION; exit}
|
24
|
+
opts.on('--try', 'Runs only if selected on puppet_controller'){ options[:try] = true }
|
25
|
+
opts.on('-f', '--facts', 'Report facts'){ options[:facts] = true }
|
26
|
+
opts.on('-v', '--verbose', 'Execute Verbose Command'){ options[:verbose] = true }
|
27
|
+
opts.on('-d', '--debug', 'With debug output'){ options[:debug] = true }
|
27
28
|
opts.on('-b x', '--branch x', 'Run this branch') do |branch|
|
28
29
|
options[:branch] = branch
|
29
30
|
end
|
30
31
|
end.parse!
|
31
32
|
|
33
|
+
PuppetContext = Runpuppet.setup_context(options)
|
32
34
|
if options[:facts]
|
33
|
-
|
35
|
+
PuppetContext.client.report_facts
|
34
36
|
else
|
35
|
-
|
36
|
-
end
|
37
|
+
PuppetContext.client.run
|
38
|
+
end
|
data/lib/ext/core.rb
ADDED
data/lib/runpuppet.rb
CHANGED
@@ -2,151 +2,41 @@ require 'open-uri'
|
|
2
2
|
require 'socket'
|
3
3
|
require 'yaml'
|
4
4
|
require 'rest-client'
|
5
|
-
require '
|
6
|
-
|
7
|
-
STDOUT.sync = true
|
8
|
-
|
9
|
-
class Runpuppet
|
10
|
-
def self.with_lock(lock_file)
|
11
|
-
recently_locked = (File.exists?(lock_file) and File.mtime(lock_file) > Time.now - 15*60)
|
12
|
-
|
13
|
-
if recently_locked
|
14
|
-
puts "can not run, lockfile #{lock_file} exists"
|
15
|
-
else
|
16
|
-
begin
|
17
|
-
`touch #{lock_file}`
|
18
|
-
yield
|
19
|
-
ensure
|
20
|
-
`rm #{lock_file}`
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
# simplified copy of rake`s sh
|
26
|
-
def self.sh(cmd)
|
27
|
-
puts cmd
|
28
|
-
IO.popen(cmd) do |pipe|
|
29
|
-
while str = pipe.gets
|
30
|
-
puts str
|
31
|
-
end
|
32
|
-
end
|
33
|
-
$?.success?
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
def self.get(path, options={})
|
38
|
-
path += (path.include?('?') ? '&' : '?')
|
39
|
-
path += "hostname=#{Socket.gethostname}&ip=#{Config.local_ip}"
|
40
|
-
begin
|
41
|
-
url = Config.puppet_controller_url + path
|
42
|
-
puts "Getting #{url}" if options[:verbose]
|
43
|
-
RestClient.get(url)
|
44
|
-
rescue Exception => e
|
45
|
-
puts e.inspect
|
46
|
-
puts "WARNING: error connecting in GET (PuppetMaster)"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
def self.post(path, params)
|
52
|
-
params[:hostname] = Socket.gethostname
|
53
|
-
params[:ip] = Config.local_ip
|
54
|
-
begin
|
55
|
-
RestClient.post "#{Config.puppet_controller_url}/puppet/#{path}", params
|
56
|
-
rescue Exception => e
|
57
|
-
puts e.inspect
|
58
|
-
puts "WARNING: error connecting in POST (PuppetMaster)"
|
59
|
-
end
|
60
|
-
end
|
5
|
+
require 'dim'
|
61
6
|
|
7
|
+
require 'ext/core'
|
8
|
+
require 'runpuppet/config'
|
9
|
+
require 'runpuppet/client'
|
10
|
+
require 'runpuppet/agent'
|
11
|
+
require 'runpuppet/logger'
|
62
12
|
|
63
|
-
|
64
|
-
with_lock(Config.lock_file) do
|
65
|
-
time = Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")
|
66
|
-
|
67
|
-
todo, branch = get("/puppet/run", options).split('-') rescue []
|
68
|
-
puts "got #{todo} with branch #{branch}" if options[:verbose]
|
69
|
-
branch ||= (options[:branch] || Config.default_branch)
|
70
|
-
if todo == 'run' or !options[:try] # try allows not running
|
71
|
-
get '/puppet/status?status=started', options
|
72
|
-
cmd = Config.command.gsub('@@branch@@', branch)
|
73
|
-
puts "#{time}: run #{branch}"
|
74
|
-
|
75
|
-
if sh(cmd)
|
76
|
-
get '/puppet/status?status=finished', options
|
77
|
-
else
|
78
|
-
get '/puppet/status?status=error', options
|
79
|
-
exit 2
|
80
|
-
end
|
81
|
-
else
|
82
|
-
puts "#{time}: nothing to do"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.report_facts(options={})
|
88
|
-
require 'facter/application'
|
89
|
-
facts = Facter::Application.run([])
|
90
|
-
post('facts', :facts => facts.to_hash)
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
class Config
|
95
|
-
def self.config
|
96
|
-
home = File.expand_path('~')
|
97
|
-
["#{home}/.runpuppet.yml", '/etc/runpuppet.yml'].each do |file|
|
98
|
-
return YAML.load(File.read(file)) if File.exist?(file)
|
99
|
-
end
|
100
|
-
raise "No runpuppet.yml found in /etc or #{home}"
|
101
|
-
end
|
102
|
-
|
103
|
-
def self.puppet_controller_url
|
104
|
-
config['puppet_controller_url'].sub(%r{/$},'')
|
105
|
-
end
|
13
|
+
STDOUT.sync = true
|
106
14
|
|
107
|
-
def self.puppet_controller_auth
|
108
|
-
extract_auth_from_url!(config['puppet_controller_url'])
|
109
|
-
end
|
110
15
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
auth.empty? ? nil : auth
|
115
|
-
end
|
16
|
+
module Runpuppet
|
17
|
+
def self.setup_context(options={})
|
18
|
+
ctx = Dim::Container.new
|
116
19
|
|
117
|
-
|
118
|
-
|
20
|
+
ctx.register(:run_options) do
|
21
|
+
options
|
119
22
|
end
|
120
23
|
|
121
|
-
|
122
|
-
|
24
|
+
ctx.register(:config) do
|
25
|
+
Runpuppet::Config.find_system_config
|
123
26
|
end
|
124
27
|
|
125
|
-
|
126
|
-
|
28
|
+
ctx.register(:client) do |context|
|
29
|
+
Runpuppet::Client.new(context)
|
127
30
|
end
|
128
31
|
|
129
|
-
|
130
|
-
|
131
|
-
require 'facter'
|
132
|
-
require 'facter/ec2'
|
133
|
-
ip = Facter.value("ec2_public_ipv4")
|
134
|
-
elsif config['local_ip_interface']
|
135
|
-
parse_local_ip_from_interface
|
136
|
-
else
|
137
|
-
config['local_ip'] or %x(ifconfig)[/192.168.\d+.\d+/] or %x(ifconfig)[/10.10.\d+.\d+/]
|
138
|
-
end
|
32
|
+
ctx.register(:agent) do |context|
|
33
|
+
Runpuppet::Agent.new(context)
|
139
34
|
end
|
140
35
|
|
141
|
-
|
142
|
-
|
143
|
-
# %x(ifconfig #{config['local_ip_interface']}).lines.grep(/inet addr/).first.match(/addr:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
|
144
|
-
%x(ip addr list #{config['local_ip_interface']}).match(/inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
|
145
|
-
return $1
|
36
|
+
ctx.register(:logger) do
|
37
|
+
Runpuppet::Logger
|
146
38
|
end
|
147
39
|
|
148
|
-
|
149
|
-
%x(arp -n -i eth0) =~ /fe:ff:ff:ff:ff/
|
150
|
-
end
|
40
|
+
return ctx
|
151
41
|
end
|
152
42
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
### http client
|
2
|
+
module Runpuppet
|
3
|
+
class Agent
|
4
|
+
attr_accessor :config
|
5
|
+
attr_accessor :run_options
|
6
|
+
def initialize(context)
|
7
|
+
@config = context.config
|
8
|
+
@run_options = context.run_options
|
9
|
+
end
|
10
|
+
|
11
|
+
##### puppet
|
12
|
+
|
13
|
+
def check_status
|
14
|
+
action, branch = get("/puppet/run", @run_options).split('-') rescue []
|
15
|
+
branch ||= (run_options[:branch] || config.default_branch)
|
16
|
+
return action, branch
|
17
|
+
end
|
18
|
+
|
19
|
+
def report_start
|
20
|
+
get '/puppet/status?status=started'
|
21
|
+
end
|
22
|
+
|
23
|
+
def report_success
|
24
|
+
get '/puppet/status?status=finished'
|
25
|
+
end
|
26
|
+
|
27
|
+
def report_failure
|
28
|
+
get '/puppet/status?status=error'
|
29
|
+
end
|
30
|
+
|
31
|
+
def report_facts
|
32
|
+
require 'facter/application'
|
33
|
+
facts = Facter::Application.run([])
|
34
|
+
post('/puppet/facts', :facts => facts.to_hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
#### base
|
38
|
+
|
39
|
+
def get(path)
|
40
|
+
begin
|
41
|
+
url = append_params_to_url(base_url(path))
|
42
|
+
puts "Getting #{url}" if run_options[:verbose]
|
43
|
+
result = RestClient.get(url)
|
44
|
+
puts "got #{result}" if run_options[:verbose]
|
45
|
+
rescue Exception => e
|
46
|
+
puts e.inspect
|
47
|
+
puts "WARNING: error connecting in GET (PuppetMaster)"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def post(path, params)
|
52
|
+
begin
|
53
|
+
RestClient.post base_url(path), append_params_to_post(params)
|
54
|
+
rescue Exception => e
|
55
|
+
puts e.inspect
|
56
|
+
puts "WARNING: error connecting in POST (PuppetMaster)"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def append_params_to_post(params)
|
61
|
+
params = params.dup
|
62
|
+
params[:hostname] = config.hostname
|
63
|
+
params[:ip] = config.local_ip
|
64
|
+
return params
|
65
|
+
end
|
66
|
+
|
67
|
+
def append_params_to_url(url)
|
68
|
+
url += (url.include?('?') ? '&' : '?')
|
69
|
+
url += "hostname=#{config.hostname}&ip=#{config.local_ip}"
|
70
|
+
url
|
71
|
+
end
|
72
|
+
|
73
|
+
def base_url(path)
|
74
|
+
"#{config.puppet_controller_url.gsub(/\/$/, '')}/#{path.gsub(/^\//, '')}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Runpuppet
|
2
|
+
class Client
|
3
|
+
attr_accessor :config
|
4
|
+
attr_accessor :run_options
|
5
|
+
attr_accessor :agent
|
6
|
+
attr_accessor :logger
|
7
|
+
def initialize(context)
|
8
|
+
@config = context.config
|
9
|
+
@run_options = context.run_options
|
10
|
+
@agent = context.agent
|
11
|
+
end
|
12
|
+
|
13
|
+
def run
|
14
|
+
with_lock(config.lock_file) do
|
15
|
+
action, branch = agent.check_status
|
16
|
+
if should_run?(action)
|
17
|
+
agent.report_start
|
18
|
+
log "run #{branch}"
|
19
|
+
|
20
|
+
if sh(run_command(branch))
|
21
|
+
agent.report_success
|
22
|
+
else
|
23
|
+
agent.report_failure
|
24
|
+
exit 2
|
25
|
+
end
|
26
|
+
else
|
27
|
+
log "nothing to do"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_command(branch)
|
33
|
+
cmd = if run_options[:verbose]
|
34
|
+
config.verbose_command
|
35
|
+
else
|
36
|
+
config.command
|
37
|
+
end
|
38
|
+
cmd.gsub('@@branch@@', branch)
|
39
|
+
end
|
40
|
+
|
41
|
+
def should_run?(action)
|
42
|
+
## always run if started without --try
|
43
|
+
(!run_options[:try] or action == 'run')
|
44
|
+
end
|
45
|
+
|
46
|
+
def with_lock(lock_file)
|
47
|
+
recently_locked = (File.exists?(lock_file) and File.mtime(lock_file) > Time.now - 15*60)
|
48
|
+
|
49
|
+
if recently_locked
|
50
|
+
log "can not run, lockfile #{lock_file} exists"
|
51
|
+
else
|
52
|
+
begin
|
53
|
+
`touch #{lock_file}`
|
54
|
+
yield
|
55
|
+
ensure
|
56
|
+
`rm #{lock_file}`
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# simplified copy of rake`s sh
|
62
|
+
def sh(cmd)
|
63
|
+
puts cmd
|
64
|
+
IO.popen(cmd) do |pipe|
|
65
|
+
while str = pipe.gets
|
66
|
+
puts str
|
67
|
+
end
|
68
|
+
end
|
69
|
+
$?.success?
|
70
|
+
end
|
71
|
+
|
72
|
+
def log(msg)
|
73
|
+
logger.log(msg)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Runpuppet
|
2
|
+
class Config
|
3
|
+
attr_accessor :config_path
|
4
|
+
attr_accessor :data
|
5
|
+
def initialize(config_path)
|
6
|
+
@config_path = config_path
|
7
|
+
load_data
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
def load_data
|
12
|
+
raise "No runpuppet.yml found in #{config_path}" unless File.exist?(config_path)
|
13
|
+
@data = YAML.load(File.read(config_path))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find_system_config
|
17
|
+
home = File.expand_path('~')
|
18
|
+
pathes = ["#{home}/.runpuppet.yml", '/etc/runpuppet.yml']
|
19
|
+
pathes.each do |file|
|
20
|
+
return Runpuppet::Config.new(file) if File.exist?(file)
|
21
|
+
end
|
22
|
+
puts "No runpuppet.yml found in #{pathes.join(' or ')}"
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
def puppet_controller_url
|
27
|
+
data['puppet_controller_url'].sub(%r{/$},'')
|
28
|
+
end
|
29
|
+
|
30
|
+
def puppet_controller_auth
|
31
|
+
extract_auth_from_url!(puppet_controller_url)
|
32
|
+
end
|
33
|
+
|
34
|
+
def extract_auth_from_url!(url)
|
35
|
+
url.sub!(%r{//(.*?):(.*?)@}, '//')
|
36
|
+
auth = [$1, $2].compact
|
37
|
+
auth.empty? ? nil : auth
|
38
|
+
end
|
39
|
+
|
40
|
+
def lock_file
|
41
|
+
data['lock_file'] || '/tmp/runpuppet.lock'
|
42
|
+
end
|
43
|
+
|
44
|
+
def command
|
45
|
+
# "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"
|
46
|
+
data['command']
|
47
|
+
end
|
48
|
+
|
49
|
+
def verbose_command
|
50
|
+
unless data['verbose_command']
|
51
|
+
puts "No verbose_command param in #{config_path} found! using normal command."
|
52
|
+
return self.command
|
53
|
+
end
|
54
|
+
data['verbose_command']
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_branch
|
58
|
+
data['branch'] || 'master'
|
59
|
+
end
|
60
|
+
|
61
|
+
def local_ip
|
62
|
+
if is_ec2?
|
63
|
+
require 'facter'
|
64
|
+
require 'facter/ec2'
|
65
|
+
ip = Facter.value("ec2_public_ipv4")
|
66
|
+
elsif data['local_ip_interface']
|
67
|
+
parse_local_ip_from_interface
|
68
|
+
else
|
69
|
+
ifconfig = read_shell('ifconfig')
|
70
|
+
data['local_ip'] or
|
71
|
+
ifconfig[/192.168.\d+.\d+/] or
|
72
|
+
ifconfig[/10.10.\d+.\d+/]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def hostname
|
77
|
+
Socket.gethostname
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_local_ip_from_interface
|
81
|
+
cmd = "ip addr list #{data['local_ip_interface']}"
|
82
|
+
read_shell(cmd).match(/inet (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?/)
|
83
|
+
return $1
|
84
|
+
end
|
85
|
+
|
86
|
+
def is_ec2?
|
87
|
+
read_shell('arp -n -i eth0') =~ /fe:ff:ff:ff:ff/
|
88
|
+
end
|
89
|
+
|
90
|
+
def read_shell(cmd)
|
91
|
+
%x(#{cmd})
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/runpuppet.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "runpuppet"
|
8
|
-
s.version = "1.0.0.
|
8
|
+
s.version = "1.0.0.rc2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Roman Heinrich"]
|
@@ -26,8 +26,23 @@ Gem::Specification.new do |s|
|
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"bin/runpuppet",
|
29
|
+
"lib/ext/core.rb",
|
29
30
|
"lib/runpuppet.rb",
|
31
|
+
"lib/runpuppet/agent.rb",
|
32
|
+
"lib/runpuppet/client.rb",
|
33
|
+
"lib/runpuppet/config.rb",
|
34
|
+
"lib/runpuppet/logger.rb",
|
30
35
|
"runpuppet.gemspec",
|
36
|
+
"sh/c",
|
37
|
+
"sh/console.rb",
|
38
|
+
"sh/test",
|
39
|
+
"test/agent_test.rb",
|
40
|
+
"test/binary_test.rb",
|
41
|
+
"test/client_test.rb",
|
42
|
+
"test/config_test.rb",
|
43
|
+
"test/fixtures/runpuppet.yml",
|
44
|
+
"test/fixtures/shell/arp_eth0.txt",
|
45
|
+
"test/fixtures/shell/ip_addr_list_eth0.txt",
|
31
46
|
"test/helper.rb"
|
32
47
|
]
|
33
48
|
s.homepage = "http://github.com/dawanda/runpuppet"
|
data/sh/console.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
|
+
require 'runpuppet'
|
data/sh/test
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rake test
|
data/test/agent_test.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
describe "Runpuppet::Agent" do
|
4
|
+
before do
|
5
|
+
@agent = TestContext.agent
|
6
|
+
end
|
7
|
+
|
8
|
+
describe :check_status do
|
9
|
+
it "returns the action for puppet and branch" do
|
10
|
+
@agent.stubs(:get).returns('run-master')
|
11
|
+
@agent.check_status.must_equal ["run", "master"]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe :base_url do
|
16
|
+
it 'works' do
|
17
|
+
@agent.base_url('/action').must_equal "http://user:pass@puppet.example.com/action"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "URL manipulation" do
|
22
|
+
before do
|
23
|
+
TestContext.config.stubs(:local_ip).returns('10.10.10.10')
|
24
|
+
TestContext.config.stubs(:hostname).returns('example-vm')
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe :append_params_to_post do
|
29
|
+
it "adds hostname and local ip to params" do
|
30
|
+
params = {}
|
31
|
+
new_params = @agent.append_params_to_post(params)
|
32
|
+
new_params[:hostname].must_equal 'example-vm'
|
33
|
+
new_params[:ip].must_equal '10.10.10.10'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe :append_params_to_url do
|
38
|
+
it "adds ip and hostname to url" do
|
39
|
+
new_url = @agent.append_params_to_url('/action')
|
40
|
+
new_url.must_equal "/action?hostname=example-vm&ip=10.10.10.10"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "appends to existing params, if needed" do
|
44
|
+
new_url = @agent.append_params_to_url('/action?some_funny_param=1')
|
45
|
+
new_url.must_equal "/action?some_funny_param=1&hostname=example-vm&ip=10.10.10.10"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/test/binary_test.rb
ADDED
data/test/client_test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
describe "Client" do
|
4
|
+
before do
|
5
|
+
@ctx = Dim::Container.new(TestContext)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe :run_command do
|
9
|
+
it "without --verbose param" do
|
10
|
+
cmd = "cd /etc/puppet/repo && git fetch && git checkout -f origin/feature && puppet apply /etc/puppet/repo/manifests/site.pp"
|
11
|
+
@ctx.client.run_command('feature').must_equal cmd
|
12
|
+
end
|
13
|
+
|
14
|
+
it "with --verbose param" do
|
15
|
+
@ctx.register(:run_options){ {:verbose => true} }
|
16
|
+
cmd = "cd /etc/puppet/repo && git fetch && git checkout -f origin/feature && /etc/puppet/repo/bin/prepare_environment.rb && puppet apply -v /etc/puppet/repo/manifests/site.pp"
|
17
|
+
@ctx.client.run_command('feature').must_equal cmd
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe :should_run? do
|
22
|
+
it "always runs without --try option" do
|
23
|
+
@ctx.register(:run_options){ {:try => false} }
|
24
|
+
@ctx.client.should_run?('branch_does_not_matter').must_equal true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "runs with --try option only for 'run' action" do
|
28
|
+
@ctx.register(:run_options){ {:try => true} }
|
29
|
+
@ctx.client.should_run?('run').must_equal true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "does not run with --try option, if not 'run' action" do
|
33
|
+
@ctx.register(:run_options){ {:try => true} }
|
34
|
+
@ctx.client.should_run?('some_random_action').must_equal false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/test/config_test.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test/helper'
|
2
|
+
|
3
|
+
describe 'Config' do
|
4
|
+
def shell_fixture(path)
|
5
|
+
File.read("test/fixtures/shell/#{path}").strip
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@config = TestContext.config
|
10
|
+
end
|
11
|
+
|
12
|
+
it "reports facts" do
|
13
|
+
ec2_facts = [["architecture", "x86_64"], ["arp", "fe:ff:ff:ff:ff:ff"], ["arp_eth0", "fe:ff:ff:ff:ff:ff"], ["domain", "eu-west-1.compute.internal"], ["ec2_ami_id", "ami-7acafc0e"], ["ec2_ami_launch_index", "0"], ["ec2_ami_manifest_path", "(unknown)"], ["ec2_block_device_mapping_ami", "/dev/sda1"], ["ec2_block_device_mapping_ephemeral0", "/dev/sdb"], ["ec2_block_device_mapping_root", "/dev/sda1"], ["ec2_hostname", "ip-10-234-151-254.eu-west-1.compute.internal"], ["ec2_instance_id", "i-cc511dba"], ["ec2_instance_type", "t1.micro"], ["ec2_kernel_id", "aki-4feec43b"], ["ec2_local_hostname", "ip-10-234-151-254.eu-west-1.compute.internal"], ["ec2_local_ipv4", "10.234.151.254"], ["ec2_placement_availability_zone", "eu-west-1a"], ["ec2_profile", "default-paravirtual"], ["ec2_public_hostname", "ec2-46-137-37-20.eu-west-1.compute.amazonaws.com"], ["ec2_public_ipv4", "46.137.37.20"], ["ec2_public_keys_0_openssh_key", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCn6ld1os3dZkdIjJ0zqOUrZWi9zODc2WEaonlPRjyxqhX5nDYJMFrvKRXAIi41TKxwGXzor55gbLb5GnLDFMHEZwtye9MH4n98DdSFu8Nxb9wZgT1xZ+UE/9+GKVAJq77yIWP5qe6iJe80JQAaO/WbinMoqBZ9YOF2MgPNIUoP/bPHZ6Fb+/3Nv1NV+aAMB2vqOlrujcGkI49vFmH6qbNKgAAyuakGSIlBab4PBPti3B+tOoLeimqL4H8iAQAWZCjinG12oUTkl07ZpU1waFUTDaKv4QvwFU4bGgZYk7hysAjE7A8NxI7ApEenbxySnkjew4zQlmPmV21u16E3kGYx node-autoscaling"], ["ec2_reservation_id", "r-7c31b10a"], ["ec2_security_groups", "default"], ["facterversion", "1.5.9"], ["fqdn", "ip-10-234-151-254.eu-west-1.compute.internal"], ["hardwareisa", "unknown"], ["hardwaremodel", "x86_64"], ["hostname", "ip-10-234-151-254"], ["id", "root"], ["interfaces", "dummy0,eql,eth0,ifb0,ifb1,lo"], ["ipaddress", "10.234.151.254"], ["ipaddress_eth0", "10.234.151.254"], ["ipaddress_lo", "127.0.0.1"], ["is_virtual", "true"], ["kernel", "Linux"], ["kernelmajversion", "2.6"], ["kernelrelease", "2.6.32-314-ec2"], ["kernelversion", "2.6.32"], ["lib", "/var/lib/puppet/facts"], ["lsbdistcodename", "lucid"], ["lsbdistdescription", "Ubuntu 10.04.2 LTS"], ["lsbdistid", "Ubuntu"], ["lsbdistrelease", "10.04"], ["lsbmajdistrelease", "10"], ["macaddress", "26:73:1b:a3:48:2a"], ["macaddress_dummy0", "26:73:1b:a3:48:2a"], ["macaddress_eth0", "12:31:3b:05:94:10"], ["macaddress_ifb0", "5e:5b:e7:92:26:c2"], ["macaddress_ifb1", "72:50:ad:1d:a1:0f"], ["memoryfree", "430.29 MB"], ["memorysize", "635.17 MB"], ["netmask", "255.255.254.0"], ["netmask_eth0", "255.255.254.0"], ["netmask_lo", "255.0.0.0"], ["network_eth0", "10.234.150.0"], ["network_lo", "127.0.0.0"], ["operatingsystem", "Ubuntu"], ["operatingsystemrelease", "10.04"], ["path", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/rvm/bin"], ["physicalprocessorcount", "1"], ["processor0", "Intel(R) Xeon(R) CPU E5430 @ 2.66GHz"], ["processorcount", "1"], ["ps", "ps -ef"], ["puppetversion", "2.6.7"], ["rubysitedir", "/usr/local/lib/ruby/site_ruby/1.8"], ["rubyversion", "1.8.7"], ["selinux", "false"], ["sshdsakey", "AAAAB3NzaC1kc3MAAACBAM2/DHTO3olTFG6lmWXNJcEYKZtFylFWCLJomNEaMMkf7qEtCLSPVWdhgYKHmk/UBPrpuzWrapVa1/eap77CNgQ6e8LmKdcgkCVcuKSLqtm+e989lb9RrcIUYYd4UXIZbLPKF3z3AOmESxikaiQs9M8x4Jn5kmpPb6fixSvOi577AAAAFQDAQMxsywSbD3W28MCI3kfrbKhEPwAAAIBm5HQwsY8VZnfLgWdkpZfcDv2V/9U+0+Atd6O37wpmF4HjIqbIbTJ1ABCXhLgo5oX2YVsRWfVLLxsmgxPoF5CLBNPQcFhNldto4H8sGkcbNFU8oBEiOgnZ6ZEax/Ooe/bO7wR+dz0F5u9IuMj4QK1GWuiAUr7U8E9Ithhe3DVq1QAAAIB3xFxOwbewB9YaeajoTfJDZzt/ovgSD3V4YYgX7mRG8Zv5UW2LduLgifwBJLWVt/Qp44STI1wON2OFRNDvhIH82+5iW3m5ifIy5c8ZviupZVpYy2adw/Ay3+bP/w0TtosmlzyWW7tj2jXVTc79ul3y9uXfZcQw8EB0ISbafy6+2Q=="], ["sshrsakey", "AAAAB3NzaC1yc2EAAAABIwAAAQEAtdvq2CjLz74rL1peJiZakeZtgeJ6lQ1vzCHseSkB3kjsPBMckz9RIec0PrLcY7BmEMfTIJJOq8OrrKdeCauRWQ47tuajVtXr+FXB0U+4FRLs2onBzUI8k2ToY8qNR7TfD5MmirBrYb26S/r0Lm8d86RkkMl4snbwEU0b42e6NbzcjVShAkbGGols7FpziqQWZY4Coo4Z2b2IBLqBZXg4N9laAsR3NlH8JclkUZ34gh5Bnzmr6b/IxTR06aIP0s0W9KEmzuHGv7S/loC1xAgxJMZf/ViLGAGf83jpnp7mMJ5Pbtbbys8tv+Jp4Jobmn/90FkMstkxpoPZX48ImwDfbQ=="], ["swapfree", "0.00 kB"], ["swapsize", "0.00 kB"], ["timezone", "CEST"], ["uniqueid", "ea0afe97"], ["uptime", "4:51 hours"], ["uptime_days", 0], ["uptime_hours", 4], ["uptime_seconds", 17517], ["virtual", "xenu"]]
|
14
|
+
end
|
15
|
+
|
16
|
+
describe :local_ip do
|
17
|
+
it 'on ec2' do
|
18
|
+
@config.stubs(:is_ec2?).returns(true)
|
19
|
+
## require factor or not?
|
20
|
+
#Facter.stubs(:value).with('ec2_public_ipv4').returns('x.x')
|
21
|
+
#@config.local_ip.must_equal 'xx'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "from ip addr, if local_ip_interface" do
|
25
|
+
@config.stubs(:is_ec2?).returns(false)
|
26
|
+
@config.data['local_ip_interface'] = 'something'
|
27
|
+
@config.stubs(:parse_local_ip_from_interface).returns('x.x.x.x')
|
28
|
+
@config.local_ip.must_equal 'x.x.x.x'
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'otherwise' do
|
32
|
+
it "from local_ip, if present" do
|
33
|
+
@config.stubs(:is_ec2?).returns(false)
|
34
|
+
@config.data['local_ip_interface'] = nil
|
35
|
+
@config.data['local_ip'] = 'x.x.x.y'
|
36
|
+
@config.local_ip.must_equal 'x.x.x.y'
|
37
|
+
end
|
38
|
+
|
39
|
+
it "from ifconfig with 192.168.x.x regex" do
|
40
|
+
|
41
|
+
end
|
42
|
+
it "from ifconfig with 10.10.x.x regex" do
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe :hostname do
|
49
|
+
it 'read from socket' do
|
50
|
+
Socket.stubs(:gethostname).returns('some_host')
|
51
|
+
@config.hostname.must_equal 'some_host'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe :is_ec2? do
|
56
|
+
it 'works' do
|
57
|
+
@config.stubs(:read_shell).returns(shell_fixture('arp_eth0.txt'))
|
58
|
+
@config.is_ec2?.must_be :>, 0
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe :parse_local_ip_from_interface do
|
63
|
+
it 'works' do
|
64
|
+
cmd = "ip addr list #{@config.data['local_ip_interface']}"
|
65
|
+
@config.stubs(:read_shell).with(cmd).returns(shell_fixture('ip_addr_list_eth0.txt'))
|
66
|
+
@config.parse_local_ip_from_interface.must_equal "10.10.10.10"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :puppet_controller_url do
|
71
|
+
it 'works' do
|
72
|
+
@config.puppet_controller_url.must_equal "http://user:pass@puppet.example.com"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "puppet_controller_auth" do
|
77
|
+
it "parses the auth info from url" do
|
78
|
+
@config.stubs(:puppet_controller_url).returns('http://user:pass@puppet.example.com')
|
79
|
+
"http://user:pass@puppet.example.com".must_equal(@config.puppet_controller_url)
|
80
|
+
['user', 'pass'].must_equal(@config.puppet_controller_auth)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe :lock_file do
|
85
|
+
it "defaults to /tmp/runpuppet.lock" do
|
86
|
+
@config.lock_file.must_equal "/tmp/runpuppet.lock"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
puppet_controller_url: http://user:pass@puppet.example.com
|
3
|
+
command: 'cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && puppet apply /etc/puppet/repo/manifests/site.pp'
|
4
|
+
verbose_command: 'cd /etc/puppet/repo && git fetch && git checkout -f origin/@@branch@@ && /etc/puppet/repo/bin/prepare_environment.rb && puppet apply -v /etc/puppet/repo/manifests/site.pp'
|
5
|
+
branch: master
|
6
|
+
local_ip: 10.10.10.10
|
7
|
+
local_ip_interface: eth0
|
data/test/helper.rb
CHANGED
@@ -13,3 +13,35 @@ require 'mocha'
|
|
13
13
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
14
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
15
|
require 'runpuppet'
|
16
|
+
|
17
|
+
def self.fixture_path(path)
|
18
|
+
"test/fixtures/#{path}"
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def create_test_context(options={})
|
23
|
+
ctx = Dim::Container.new
|
24
|
+
|
25
|
+
ctx.register(:config) do
|
26
|
+
Runpuppet::Config.new(fixture_path('runpuppet.yml'))
|
27
|
+
end
|
28
|
+
|
29
|
+
ctx.register(:client) do |context|
|
30
|
+
Runpuppet::Client.new(context)
|
31
|
+
end
|
32
|
+
|
33
|
+
ctx.register(:agent) do |context|
|
34
|
+
Runpuppet::Agent.new(context)
|
35
|
+
end
|
36
|
+
|
37
|
+
ctx.register(:run_options) do
|
38
|
+
{}
|
39
|
+
end
|
40
|
+
|
41
|
+
ctx.register(:logger) do
|
42
|
+
Runpuppet::Logger
|
43
|
+
end
|
44
|
+
return ctx
|
45
|
+
end
|
46
|
+
|
47
|
+
TestContext = create_test_context({})
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: runpuppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3495532457
|
5
5
|
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
9
|
- 0
|
10
10
|
- rc
|
11
|
-
-
|
12
|
-
version: 1.0.0.
|
11
|
+
- 2
|
12
|
+
version: 1.0.0.rc2
|
13
13
|
platform: ruby
|
14
14
|
authors:
|
15
15
|
- Roman Heinrich
|
@@ -141,8 +141,23 @@ files:
|
|
141
141
|
- Rakefile
|
142
142
|
- VERSION
|
143
143
|
- bin/runpuppet
|
144
|
+
- lib/ext/core.rb
|
144
145
|
- lib/runpuppet.rb
|
146
|
+
- lib/runpuppet/agent.rb
|
147
|
+
- lib/runpuppet/client.rb
|
148
|
+
- lib/runpuppet/config.rb
|
149
|
+
- lib/runpuppet/logger.rb
|
145
150
|
- runpuppet.gemspec
|
151
|
+
- sh/c
|
152
|
+
- sh/console.rb
|
153
|
+
- sh/test
|
154
|
+
- test/agent_test.rb
|
155
|
+
- test/binary_test.rb
|
156
|
+
- test/client_test.rb
|
157
|
+
- test/config_test.rb
|
158
|
+
- test/fixtures/runpuppet.yml
|
159
|
+
- test/fixtures/shell/arp_eth0.txt
|
160
|
+
- test/fixtures/shell/ip_addr_list_eth0.txt
|
146
161
|
- test/helper.rb
|
147
162
|
homepage: http://github.com/dawanda/runpuppet
|
148
163
|
licenses:
|