percheron 0.7.8 → 0.7.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab4029c23cb8f0a448262aeb764830a1e316cf76
4
- data.tar.gz: 38c2f479439afb7d69117272c1fff74f5041c880
3
+ metadata.gz: b678eef204ffac98f7d6acd4a3662d4a63cb84f1
4
+ data.tar.gz: ba9c1ed0a6d2ac94227f68358fe375be5223e211
5
5
  SHA512:
6
- metadata.gz: 67689cafe1f650f03a5bf8defe0fc9d2f207d346e93f9cdcfc4e264c0f17852b44456525a3b87ef6cc6939e30c3e6baec9d375bb2c63fe41bfa49d12cd69b393
7
- data.tar.gz: 73d86345a6c9ac3e8759fa7e3d4824d89c7af2640ed33129efa0d0b81db97708d6dd60ffa536996c8016df68e1fe72a058298303f002b066217e7574e908a446
6
+ metadata.gz: 688ffbead7b0363bf147ad733a8753f30208a317cb5c3fb64740edaeba024aa79ded4a29c7a02d962edae4c66530bca27a809b2df393e4ca740ab2e5418282a1
7
+ data.tar.gz: 50b5c69bed848d0498f7630e6e220ce26ce8aabb078c9a1cde09eab41ec9518c91d11e85e305bb85429d9f107bc65ce8eec9e55ea55cc72102540a90a3b6fbbe
data/.travis.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  before_install: gem install bundler --version 1.9.7
3
+ gemfile: Gemfile.travis
3
4
  rvm:
4
5
  - 2.0
5
6
  - 2.1
data/Gemfile CHANGED
@@ -7,6 +7,5 @@ group :test do
7
7
  end
8
8
 
9
9
  group :development do
10
- gem 'pry-byebug', '~> 3.0', platforms: [ :ruby_20, :ruby_21 ], require: false
11
- gem 'awesome_print', '~> 1.0', require: false
10
+ gem 'ruby-filemagic', '~> 0.6', require: false
12
11
  end
data/Gemfile.travis ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'codeclimate-test-reporter', '~> 0.1', require: false
7
+ end
data/README.md CHANGED
@@ -16,6 +16,7 @@ Organise your Docker containers with muscle and intelligence.
16
16
  * Build 'base' images as a dependancy and then build from there
17
17
  * Support for pre-build and post-start scripts when generating images and starting containers
18
18
  * Version control of building images and containers
19
+ * Generate Graphviz dependancy graphs dynamically
19
20
  * Written in Ruby :)
20
21
 
21
22
  ## Supported platforms
@@ -67,6 +68,7 @@ docker:
67
68
 
68
69
  stacks:
69
70
  - name: consul-stack
71
+ description: A demo consul stack with one master and two agents
70
72
  units:
71
73
  - name: master
72
74
  version: 1.0.0
@@ -77,6 +79,7 @@ stacks:
77
79
  - 8600:53/udp
78
80
  - name: agent
79
81
  version: 1.0.0
82
+ instances: 2
80
83
  docker_image: progrium/consul:latest
81
84
  start_args: "-server -join master"
82
85
  dependant_unit_names:
@@ -95,15 +98,21 @@ percheron start consul-stack
95
98
  open http://boot2docker:8500/ui
96
99
  ```
97
100
 
98
- 5) Perform a DNS lookup
101
+ 5) Perform some DNS lookups
99
102
 
100
103
  ```bash
101
104
  dig @boot2docker -p 8600 master.node.consul +short
105
+ dig @boot2docker -p 8600 agent1.node.consul +short
106
+ dig @boot2docker -p 8600 agent2.node.consul +short
102
107
  ```
103
108
 
109
+ ## Dependancy graph
110
+
111
+ ![consul-stack](https://raw.githubusercontent.com/ashmckenzie/percheron-consul/master/assets/stack.png)
112
+
104
113
  ## Demo
105
114
 
106
- [![asciicast](https://asciinema.org/a/19216.png)](https://asciinema.org/a/19216)
115
+ [![asciicast](https://asciinema.org/a/7l1ar35xlmfsaphhptrqvx7jg.png)](https://asciinema.org/a/7l1ar35xlmfsaphhptrqvx7jg)
107
116
 
108
117
  ## Debugging
109
118
 
@@ -113,14 +122,17 @@ To perform debugging you will need to install the `pry-byebug` gem:
113
122
  gem install pry-byebug
114
123
  ```
115
124
 
116
- To debug Percheron, set the `DEBUG=true` environment variable. To debug Percheron and Docker, set the `DOCKER_DEBUG=true` environment variable.
125
+ To debug Percheron, set the `DEBUG=true` environment variable.
126
+
127
+ To debug Percheron and Docker, set the `DOCKER_DEBUG=true` environment variable.
117
128
 
118
129
  ## Examples
119
130
 
131
+ * [consul](https://github.com/ashmckenzie/percheron-consul) - consul server + UI and two agents
120
132
  * [Rails](https://github.com/ashmckenzie/percheron-rails#quickstart) - Rails 4.2, PostgreSQL, redis, HAProxy and postfix
121
133
  * [Redis](https://github.com/ashmckenzie/percheron-redis#quickstart) - Redis cluster + sentinel, master, two slaves and tools
122
134
  * [Torrent](https://github.com/ashmckenzie/percheron-torrent#quickstart) - Tracker (chihaya), seeder (aria2) and three peers (aria2)
123
- * [SaltStack](https://github.com/ashmckenzie/percheron-saltstack#quickstart) - SaltStack v2015.2.0rc2 with master and minion
135
+ * [SaltStack](https://github.com/ashmckenzie/percheron-saltstack#quickstart) - SaltStack v2015.5.0 with master and two minions
124
136
 
125
137
  ## Testing
126
138
 
data/bin/percheron CHANGED
@@ -11,4 +11,5 @@ begin
11
11
  Percheron::Commands::Main.run
12
12
  rescue => e
13
13
  puts Percheron::OhDear.new(e).generate
14
+ exit(1)
14
15
  end
@@ -0,0 +1,18 @@
1
+ module Percheron
2
+ module Commands
3
+ class Graph < Abstract
4
+
5
+ parameter('STACK_NAME', 'stack name', required: true)
6
+ option([ '-o', '--output' ], 'OUTPUT', 'Output file')
7
+
8
+ def execute
9
+ super
10
+ stack.graph!(output || default_output)
11
+ end
12
+
13
+ def default_output
14
+ 'percheron_%s.png' % stack.name
15
+ end
16
+ end
17
+ end
18
+ end
@@ -12,6 +12,7 @@ module Percheron
12
12
  subcommand 'purge', 'Purge a stack', Purge
13
13
  subcommand 'shell', 'Shell into a unit', Shell
14
14
  subcommand 'logs', 'Show logs for a unit', Logs
15
+ subcommand 'graph', 'Generate a stack graph', Graph
15
16
  end
16
17
  end
17
18
  end
@@ -12,6 +12,7 @@ require 'percheron/commands/build'
12
12
  require 'percheron/commands/recreate'
13
13
  require 'percheron/commands/shell'
14
14
  require 'percheron/commands/logs'
15
+ require 'percheron/commands/graph'
15
16
  require 'percheron/commands/main'
16
17
 
17
18
  module Percheron
@@ -0,0 +1,103 @@
1
+ require 'graphviz'
2
+
3
+ module Percheron
4
+ class Graph
5
+
6
+ def initialize(stack)
7
+ @stack = stack
8
+ @nodes = {}
9
+ @graphs = {}
10
+ end
11
+
12
+ def save!(file)
13
+ generate
14
+ save(file)
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :stack
20
+ attr_accessor :nodes, :graphs
21
+
22
+ def generate
23
+ add_nodes
24
+ add_links
25
+ end
26
+
27
+ def save(file)
28
+ graph.output(png: file)
29
+ end
30
+
31
+ def graph
32
+ @graph ||= GraphViz.new(:G, graph_opts)
33
+ end
34
+
35
+ def graph_opts
36
+ { type: :digraph, nodesep: 0.75, ranksep: 1.0, label: header_label, fontsize: 12 }
37
+ end
38
+
39
+ def units
40
+ @units ||= stack.units
41
+ end
42
+
43
+ def header_label
44
+ '\n%s\n%s\n' % [ stack.name, stack.description ]
45
+ end
46
+
47
+ def add_nodes
48
+ units.each do |_, unit|
49
+ if unit.pseudo?
50
+ add_pseudo_node(unit)
51
+ else
52
+ add_node(unit)
53
+ end
54
+ end
55
+ end
56
+
57
+ def add_node(unit)
58
+ nodes[unit.name] = graph.add_nodes(unit.name, node_opts(unit))
59
+ end
60
+
61
+ def add_pseudo_node(unit)
62
+ create_cluster(unit)
63
+ nodes[unit.name] = graphs[unit.pseudo_name].add_nodes(unit.name, pseudo_node_opts(unit))
64
+ end
65
+
66
+ def create_cluster(unit)
67
+ return nil if graphs[unit.pseudo_name]
68
+ opts = 'cluster%s' % graphs.keys.count, cluster_opts(unit)
69
+ graphs[unit.pseudo_name] = graph.add_graph(opts)
70
+ end
71
+
72
+ def cluster_opts(unit)
73
+ { label: unit.pseudo_name, style: 'filled', color: 'lightgrey' }
74
+ end
75
+
76
+ def node_opts(unit)
77
+ shape = unit.startable? ? 'box' : 'ellipse'
78
+ label = [ unit.name ]
79
+ unit.ports.each { |ports| label << 'public: %s, internal: %s' % ports.split(':') }
80
+ { shape: shape, label: label.join("\n"), fontname: 'arial', fontsize: 12 }
81
+ end
82
+
83
+ def pseudo_node_opts(unit)
84
+ node_opts(unit).merge!(style: 'filled', color: 'white')
85
+ end
86
+
87
+ def add_links
88
+ units.each do |name, unit|
89
+ unit.dependant_units.each do |dependant_name, dependant_unit|
90
+ graph.add_edges(nodes[name], nodes[dependant_name], node_link_opts(dependant_unit))
91
+ end
92
+ end
93
+ end
94
+
95
+ def node_link_opts(unit)
96
+ direction = unit.startable? ? 'forward' : 'none'
97
+ style = unit.startable? ? 'solid' : 'solid'
98
+ color = unit.startable? ? 'black' : 'gray'
99
+ { dir: direction, style: style, color: color }
100
+ end
101
+
102
+ end
103
+ end
@@ -5,9 +5,11 @@ $logger = Logger.new(STDOUT)
5
5
  logger_level = Logger::INFO
6
6
  logger_level = Logger::WARN if ENV['QUIET'] == 'true'
7
7
 
8
+ # :nocov:
8
9
  if ENV['DEBUG'] == 'true' || ENV['DOCKER_DEBUG'] == 'true'
9
10
  logger_level = Logger::DEBUG
10
11
  Docker.logger = $logger if ENV['DOCKER_DEBUG'] == 'true'
11
12
  end
13
+ # :nocov:
12
14
 
13
15
  $logger.level = logger_level
@@ -36,6 +36,11 @@ module Percheron
36
36
  end
37
37
  end
38
38
 
39
+ def graph!(file)
40
+ Graph.new(self).save!(file)
41
+ $logger.info "Saved '%s'" % file
42
+ end
43
+
39
44
  def shell!(unit_name, command: Percheron::Actions::Shell::DEFAULT_COMMAND)
40
45
  Actions::Shell.new(unit_from_name(unit_name), command: command).execute!
41
46
  end
@@ -118,7 +118,7 @@ module Percheron
118
118
 
119
119
  def update_dockerfile_md5!
120
120
  md5 = current_dockerfile_md5
121
- $logger.info "Setting MD5 for '#{name}' unit to #{md5}"
121
+ $logger.debug "Setting MD5 for '#{name}' unit to #{md5}"
122
122
  $metastore.set("#{metastore_key}.dockerfile_md5", md5)
123
123
  end
124
124
 
@@ -150,6 +150,10 @@ module Percheron
150
150
  Validators::Unit.new(self).valid?
151
151
  end
152
152
 
153
+ def pseudo?
154
+ !pseudo_name.nil?
155
+ end
156
+
153
157
  alias_method :startable?, :startable
154
158
 
155
159
  private
@@ -172,8 +176,5 @@ module Percheron
172
176
  Hashie::Mash.new(container.info)
173
177
  end
174
178
 
175
- def pseudo?
176
- !pseudo_name.nil?
177
- end
178
179
  end
179
180
  end
@@ -1,3 +1,3 @@
1
1
  module Percheron
2
- VERSION = '0.7.8'
2
+ VERSION = '0.7.9'
3
3
  end
data/lib/percheron.rb CHANGED
@@ -15,6 +15,7 @@ require 'percheron/config'
15
15
  require 'percheron/errors'
16
16
  require 'percheron/config_delegator'
17
17
  require 'percheron/formatters'
18
+ require 'percheron/graph'
18
19
  require 'percheron/stack'
19
20
  require 'percheron/null_stack'
20
21
  require 'percheron/unit'
data/percheron.gemspec CHANGED
@@ -27,10 +27,12 @@ Gem::Specification.new do |spec|
27
27
  spec.add_runtime_dependency 'metastore', '~> 0.3'
28
28
  spec.add_runtime_dependency 'highline', '~> 1.7.1'
29
29
  spec.add_runtime_dependency 'liquid', '~> 3.0'
30
+ spec.add_runtime_dependency 'ruby-graphviz', '~> 1.2'
30
31
 
31
32
  spec.add_development_dependency 'bundler', '~> 1.9'
32
33
  spec.add_development_dependency 'rake', '~> 10.0'
33
34
  spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'pry-byebug', '~> 3.1'
34
36
  spec.add_development_dependency 'guard-rspec', '~> 4.5'
35
37
  spec.add_development_dependency 'simplecov', '~> 0.9'
36
38
  spec.add_development_dependency 'timecop', '~> 0.7'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: percheron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ash McKenzie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-14 00:00:00.000000000 Z
11
+ date: 2015-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: ruby-graphviz
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.2'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.2'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bundler
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +192,20 @@ dependencies:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
194
  version: '3.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: pry-byebug
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '3.1'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '3.1'
181
209
  - !ruby/object:Gem::Dependency
182
210
  name: guard-rspec
183
211
  requirement: !ruby/object:Gem::Requirement
@@ -277,6 +305,7 @@ files:
277
305
  - ".travis.yml"
278
306
  - CODE_OF_CONDUCT.md
279
307
  - Gemfile
308
+ - Gemfile.travis
280
309
  - Guardfile
281
310
  - LICENSE.txt
282
311
  - README.md
@@ -301,6 +330,7 @@ files:
301
330
  - lib/percheron/commands/build.rb
302
331
  - lib/percheron/commands/console.rb
303
332
  - lib/percheron/commands/create.rb
333
+ - lib/percheron/commands/graph.rb
304
334
  - lib/percheron/commands/list.rb
305
335
  - lib/percheron/commands/logs.rb
306
336
  - lib/percheron/commands/main.rb
@@ -318,6 +348,7 @@ files:
318
348
  - lib/percheron/formatters.rb
319
349
  - lib/percheron/formatters/stack.rb
320
350
  - lib/percheron/formatters/stack/table.rb
351
+ - lib/percheron/graph.rb
321
352
  - lib/percheron/logger.rb
322
353
  - lib/percheron/metastore.rb
323
354
  - lib/percheron/null_stack.rb