dnapi 1.1.74.jruby192.c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/lib/dnapi.rb +54 -0
  2. data/lib/dnapi/app.rb +130 -0
  3. data/lib/dnapi/component.rb +50 -0
  4. data/lib/dnapi/component_possessor.rb +49 -0
  5. data/lib/dnapi/components/addons.rb +26 -0
  6. data/lib/dnapi/components/apache.rb +13 -0
  7. data/lib/dnapi/components/cloudkick.rb +13 -0
  8. data/lib/dnapi/components/encrypted_backup.rb +12 -0
  9. data/lib/dnapi/components/exim.rb +10 -0
  10. data/lib/dnapi/components/monitor.rb +12 -0
  11. data/lib/dnapi/components/nagios.rb +28 -0
  12. data/lib/dnapi/components/newrelic.rb +12 -0
  13. data/lib/dnapi/components/passenger3.rb +13 -0
  14. data/lib/dnapi/components/ruby.rb +234 -0
  15. data/lib/dnapi/components/ssmtp.rb +10 -0
  16. data/lib/dnapi/components/stunneled.rb +13 -0
  17. data/lib/dnapi/components/volume.rb +32 -0
  18. data/lib/dnapi/cron.rb +5 -0
  19. data/lib/dnapi/db_stack.rb +92 -0
  20. data/lib/dnapi/ebuild_dep.rb +5 -0
  21. data/lib/dnapi/environment.rb +327 -0
  22. data/lib/dnapi/extensions.rb +32 -0
  23. data/lib/dnapi/gem_dep.rb +9 -0
  24. data/lib/dnapi/instance.rb +69 -0
  25. data/lib/dnapi/monitoring.rb +22 -0
  26. data/lib/dnapi/recipe.rb +27 -0
  27. data/lib/dnapi/ssl_cert.rb +13 -0
  28. data/lib/dnapi/stack.rb +111 -0
  29. data/lib/dnapi/struct.rb +149 -0
  30. data/lib/dnapi/test.rb +114 -0
  31. data/lib/dnapi/test/ext.rb +32 -0
  32. data/lib/dnapi/test/sweatshop.rb +148 -0
  33. data/lib/dnapi/version.rb +3 -0
  34. data/lib/dnapi/vhost.rb +24 -0
  35. data/spec/app_spec.rb +68 -0
  36. data/spec/component_spec.rb +66 -0
  37. data/spec/components/addons_spec.rb +33 -0
  38. data/spec/components/cloudkick_spec.rb +17 -0
  39. data/spec/components/nagios_spec.rb +42 -0
  40. data/spec/components/nodejs_spec.rb +27 -0
  41. data/spec/components/passenger3_spec.rb +12 -0
  42. data/spec/components/ruby_spec.rb +321 -0
  43. data/spec/components/stunneled.rb +15 -0
  44. data/spec/components/volume_spec.rb +21 -0
  45. data/spec/db_stack_spec.rb +111 -0
  46. data/spec/environment_spec.rb +227 -0
  47. data/spec/instance_spec.rb +52 -0
  48. data/spec/proxies.rb +143 -0
  49. data/spec/proxies_spec.rb +76 -0
  50. data/spec/spec_helper.rb +2 -0
  51. data/spec/stack_spec.rb +105 -0
  52. data/spec/struct_spec.rb +100 -0
  53. metadata +181 -0
data/lib/dnapi.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'forwardable'
2
+ require 'extlib'
3
+ require 'json'
4
+
5
+ module DNApi
6
+ def self.build(attributes = {})
7
+ Environment.new(attributes)
8
+ end
9
+
10
+ def self.from(json)
11
+ jexp = (String === json) ? JSON.parse(json) : json
12
+
13
+ engineyard = jexp["engineyard"]
14
+ environment = Environment.from(engineyard["environment"])
15
+ environment.instance_for(engineyard["this"])
16
+ end
17
+
18
+ def self.components
19
+ @components ||= []
20
+ end
21
+
22
+ def self.component(name, &block)
23
+ klass = Class.new(Component, &block)
24
+ klass.name = name
25
+
26
+ self.components << klass
27
+
28
+ klass
29
+ end
30
+
31
+ class InstanceNotFound < StandardError; end
32
+ end
33
+
34
+ require 'dnapi/component'
35
+ require 'dnapi/extensions'
36
+ require 'dnapi/struct'
37
+ require 'dnapi/component_possessor'
38
+ require 'dnapi/recipe'
39
+ require 'dnapi/db_stack'
40
+ require 'dnapi/monitoring'
41
+ require 'dnapi/instance'
42
+ require 'dnapi/environment'
43
+ require 'dnapi/app'
44
+ require 'dnapi/ebuild_dep'
45
+ require 'dnapi/gem_dep'
46
+ require 'dnapi/cron'
47
+ require 'dnapi/ssl_cert'
48
+ require 'dnapi/vhost'
49
+
50
+ require 'dnapi/components/versioned_component'
51
+ Dir[File.join(File.dirname(__FILE__), 'dnapi', 'components', '*')].each do |component_file|
52
+ require component_file
53
+ end
54
+ require 'dnapi/stack'
data/lib/dnapi/app.rb ADDED
@@ -0,0 +1,130 @@
1
+ module DNApi
2
+ class App < Struct.new(:deploy_key, :repository_name, :type, :branch,
3
+ :deploy_action, :migration_command, :revision,
4
+ :run_deploy, :run_migrations, :name, :bundled,
5
+ :newrelic, :database_name)
6
+
7
+ include ComponentPossessor
8
+
9
+ belongs_to :environment
10
+ many :gems, :ebuilds, :vhosts
11
+
12
+ def initialize(attributes = {})
13
+ gem_attributes = attributes.delete(:gems)
14
+ ebuild_names = attributes.delete(:ebuilds)
15
+
16
+ super(attributes)
17
+
18
+ gem_attributes.each {|attrs| build_gem(attrs) } if gem_attributes
19
+ ebuild_names.each {|name| build_ebuild(:name => name) } if ebuild_names
20
+ vhosts.each {|vhost| vhost.app = self } if vhosts
21
+ end
22
+
23
+ def build_vhost(attributes = {})
24
+ vhost = VHost.new(attributes)
25
+ vhost.app = self
26
+ vhosts << vhost
27
+ vhost
28
+ end
29
+
30
+ def domain_name
31
+ vhosts.map {|vhost| vhost.domain_name }.compact.first
32
+ end
33
+
34
+ def domain_name=(value)
35
+ if vhosts.empty?
36
+ build_vhost(:domain_name => value)
37
+ else
38
+ vhosts.first.domain_name = value
39
+ end
40
+ end
41
+
42
+ def ssl_cert
43
+ vhosts.map {|vhost| vhost.ssl_cert }.compact.first
44
+ end
45
+
46
+ def ssl_cert=(attributes = {})
47
+ if vhosts.empty?
48
+ build_vhost.build_ssl_cert(attributes || {})
49
+ else
50
+ vhosts.first.build_ssl_cert(attributes || {})
51
+ end
52
+ end
53
+
54
+ def https?
55
+ vhosts.any? {|vhost| vhost.https? }
56
+ end
57
+
58
+ def bundled?
59
+ !! bundled
60
+ end
61
+
62
+ def newrelic?
63
+ !! newrelic
64
+ end
65
+
66
+ def to_legacy_hash
67
+ shared = %w( deploy_key repository_name type branch
68
+ deploy_action migration_command revision
69
+ run_deploy run_migrations )
70
+ data = to_hash.select {|k,v| shared.include?(k.to_s)}
71
+ Hash[*data.flatten].merge(
72
+ :newrelic => newrelic?,
73
+ :vhosts => vhost_legacy_array,
74
+ :recipes => recipe_names,
75
+ :http_bind_port => 80,
76
+ :https_bind_port => 443,
77
+ :auth => {:active => false},
78
+ :services => [{
79
+ :resource => :mongrel,
80
+ :mongrel_base_port => 5000,
81
+ :mongrel_mem_limit => 150,
82
+ :mongrel_instance_count => 3
83
+ },
84
+ {
85
+ :resource => :memcached,
86
+ :base_port => 11211,
87
+ :mem_limit => 128
88
+ }]
89
+ )
90
+ end
91
+
92
+ def vhost_legacy_array
93
+ array = vhosts.map {|vhost| vhost.to_legacy_hash }
94
+ vhosts.select {|vhost| vhost.https? }.inject(array) {|a,vhost| a.push(vhost.to_legacy_hash(true)) } if https? # legacy shit has 2 entries for an https vhost
95
+ array
96
+ end
97
+
98
+ def gems_hash
99
+ gems.map do |gem|
100
+ gem.to_legacy_hash
101
+ end
102
+ end
103
+
104
+ def recipes
105
+ Recipe.defaults + environment.stack.recipes
106
+ end
107
+
108
+ def jruby?
109
+ environment.ruby_component.is_a?(DNApi::Components::JRuby)
110
+ end
111
+
112
+ def recipe_names
113
+ recipes.map {|r| r.name }
114
+ end
115
+
116
+ def build_gem(attributes = {})
117
+ gem = GemDep.new(attributes)
118
+ gem.app = self
119
+ gems << gem
120
+ gem
121
+ end
122
+
123
+ def build_ebuild(attributes = {})
124
+ ebuild = EbuildDep.new(attributes)
125
+ ebuild.app = self
126
+ ebuilds << ebuild
127
+ ebuild
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,50 @@
1
+ module DNApi
2
+ module Component
3
+ class NoSuchComponent < StandardError; end
4
+
5
+ module ClassExt
6
+ attr_accessor :description, :key_id, :parent, :stack_versions
7
+ alias_method :key, :key_id=
8
+ alias_method :desc, :description=
9
+ alias_method :versions, :stack_versions=
10
+
11
+ def belongs_to(klass)
12
+ name = klass.name.split(/::/).last.downcase
13
+ self.send :alias_method, name, :parent
14
+ self.send :alias_method, "#{name}=", :parent=
15
+ @parent = klass
16
+ end
17
+ end
18
+
19
+ def self.included(receiver)
20
+ components << receiver
21
+ receiver.send(:attr_accessor, :parent)
22
+ receiver.extend ClassExt
23
+ end
24
+
25
+ def self.components
26
+ @components ||= []
27
+ end
28
+
29
+ def self.[](key)
30
+ components.detect {|c| c.key_id == key } or raise NoSuchComponent, "unknown component #{key.inspect}"
31
+ end
32
+
33
+ def self.from(values)
34
+ self[values.delete('key').to_sym].new(values)
35
+ end
36
+
37
+ def key
38
+ self::class.key_id
39
+ end
40
+
41
+ def to_hash
42
+ super.merge('key' => key)
43
+ end
44
+
45
+ def can_belong_to?(model)
46
+ self.class.parent === model
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,49 @@
1
+ module DNApi
2
+ module ComponentPossessor
3
+
4
+ class ComponentAttachmentError < StandardError; end
5
+
6
+ module Ext
7
+ def component_group_map
8
+ @component_group_map ||= {}
9
+ end
10
+
11
+ def component_group(name, *keys)
12
+ define_method(name.to_sym) do
13
+ component_group(name)
14
+ end
15
+ component_group_map[name.to_sym] = keys
16
+ end
17
+ end
18
+
19
+ def has_component?(key)
20
+ components.any? {|c| c.key == key }
21
+ end
22
+
23
+ alias_method :component?, :has_component?
24
+
25
+ def component(key)
26
+ components.detect {|c| c.key == key }
27
+ end
28
+
29
+ def component_group(group_key)
30
+ component_keys = self::class.component_group_map[group_key.to_sym] || []
31
+ component_keys.map {|key| components.select {|c| c.key == key } }.flatten
32
+ end
33
+
34
+ def self.included(receiver)
35
+ receiver.extend(Ext)
36
+ receiver.send :many, :components
37
+ end
38
+
39
+ def add_component(key, component_options={})
40
+ c = Component[key.to_sym].new(component_options.merge(:parent => self))
41
+ unless c.can_belong_to?(self)
42
+ raise ComponentAttachmentError, "Can't attach #{key.inspect} to a #{self.class}"
43
+ end
44
+
45
+ components << c
46
+ c
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,26 @@
1
+ module DNApi
2
+ module Components
3
+ class Addons < Struct.new(:collection)
4
+ include Component
5
+
6
+ desc "Configuration for simple heroku-style third party addons"
7
+
8
+ key :addons
9
+
10
+ belongs_to App
11
+
12
+ def initialize(attrs = {})
13
+ attrs[:collection] = (attrs['collection'] || attrs[:collection]).collect{ |v| Addon.new(v) }
14
+ super attrs
15
+ end
16
+
17
+ def each(&block)
18
+ collection.each(&block)
19
+ end
20
+ include Enumerable
21
+
22
+ class Addon < Struct.new(:name, :config)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ module DNApi
2
+ module Components
3
+ class Apache < Struct.new(:key)
4
+ include Component
5
+
6
+ desc "Use Apache instead of Nginx for the frontend server."
7
+
8
+ key :apache
9
+
10
+ belongs_to Environment
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module DNApi
2
+ module Components
3
+ class Cloudkick < Struct.new(:name, :oauth_key, :oauth_secret, :tags)
4
+ include Component
5
+
6
+ desc "A 3rd party service for instance monitoring."
7
+
8
+ key :cloudkick
9
+
10
+ belongs_to Instance
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module DNApi
2
+ module Components
3
+ class EncryptedBackup < Struct.new(:public_key)
4
+ include Component
5
+ desc "Enable encrypted backup support (so your customer's boss's boss will STFU)."
6
+
7
+ key :encrypted_backup
8
+
9
+ belongs_to App
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module DNApi
2
+ module Components
3
+ class Exim < Struct.new(:user, :password, :host, :outbound_host)
4
+ include Component
5
+
6
+ key :exim
7
+ belongs_to Instance
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ module DNApi
2
+ module Components
3
+ class GodMonitor < Struct.new(:key)
4
+ include Component
5
+ desc "Monitor services with god."
6
+
7
+ key :god
8
+
9
+ belongs_to Environment
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ module DNApi
2
+ module Components
3
+ class Nagios < Struct.new(:master_key, :endpoint)
4
+ include Component
5
+ desc "Monitor the instances with nagios."
6
+
7
+ key :nagios
8
+
9
+ belongs_to Instance
10
+
11
+ def master_instance
12
+ instance.environment.instances.detect {|i| i.id == master_key }
13
+ end
14
+
15
+ def master?
16
+ master_instance == instance
17
+ end
18
+
19
+ def monitored_instances
20
+ if master?
21
+ instance.environment.instances
22
+ else
23
+ [master_instance]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module DNApi
2
+ module Components
3
+ class Newrelic < Struct.new(:token, :seed)
4
+ include Component
5
+ desc "Enable newrelic support."
6
+
7
+ key :newrelic
8
+
9
+ belongs_to Instance
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module DNApi
2
+ module Components
3
+ class Passenger3 < Struct.new(:key)
4
+ include Component
5
+
6
+ desc "The latest stable version of the passenger web stack."
7
+
8
+ key :passenger3
9
+
10
+ belongs_to Environment
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,234 @@
1
+ module DNApi
2
+ module Components
3
+ class RubyVersion < VersionedComponent.new(:key)
4
+ def self.all
5
+ [ DNApi::Components::Ruby186,
6
+ DNApi::Components::Ruby187,
7
+ DNApi::Components::REE,
8
+ DNApi::Components::JRuby187,
9
+ DNApi::Components::JRuby192,
10
+ DNApi::Components::Rubinius,
11
+ DNApi::Components::Ruby193,
12
+ DNApi::Components::Ruby192 ]
13
+ end
14
+
15
+ def self.encoding_aware
16
+ [DNApi::Components::Ruby192, DNApi::Components::Ruby193, DNApi::Components::Rubinius]
17
+ end
18
+
19
+ NAME = 'Ruby'.freeze
20
+ RUBYGEMS_VERSION = '1.5.2'.freeze
21
+
22
+ def rubygems_version
23
+ self.class::RUBYGEMS_VERSION
24
+ end
25
+
26
+ def ruby_version
27
+ "#{version}_p#{patch_level}"
28
+ end
29
+
30
+ def ruby_flavor
31
+ 'dev-lang/ruby'
32
+ end
33
+
34
+ def ruby_module
35
+ 'ruby18'
36
+ end
37
+
38
+ # This shit is used by old versions of cloud_cookbooks and
39
+ # we can't remove it without breaking the ones that didn't upgrade.
40
+ #
41
+ # The latest versions of the cookbooks won't use this anymore.
42
+ # To know how to specify a database adapter see DNApi::DbStack#adapter_for
43
+ #
44
+ def mysql_adapter
45
+ 'mysql'
46
+ end
47
+ end
48
+
49
+ class Ruby186 < RubyVersion
50
+ include Component
51
+
52
+ desc "Legacy version of Ruby 1.8"
53
+
54
+ key :ruby_186
55
+
56
+ belongs_to Environment
57
+
58
+ VERSION = '1.8.6'.freeze
59
+ PATCH_LEVEL = '420'.freeze
60
+ RUBYGEMS_VERSION = '1.4.2'.freeze
61
+ end
62
+
63
+ class Ruby187 < RubyVersion
64
+ include Component
65
+
66
+ desc "Modern version of Ruby 1.8"
67
+
68
+ key :ruby_187
69
+
70
+ belongs_to Environment
71
+
72
+ VERSION = '1.8.7'.freeze
73
+ PATCH_LEVEL = '352'.freeze
74
+ end
75
+
76
+ class REE < RubyVersion
77
+ include Component
78
+
79
+ desc "Ruby Enterprise Edition"
80
+
81
+ key :ree
82
+
83
+ belongs_to Environment
84
+
85
+ NAME = 'REE'.freeze
86
+ VERSION = '1.8.7'.freeze
87
+ PATCH_LEVEL = '2011.03'.freeze
88
+
89
+ def self.label
90
+ "#{self::NAME} #{self::PATCH_LEVEL}"
91
+ end
92
+
93
+ def ruby_version
94
+ "#{version}.#{patch_level}"
95
+ end
96
+
97
+ def ruby_flavor
98
+ 'dev-lang/ruby-enterprise'
99
+ end
100
+
101
+ def ruby_module
102
+ 'rubyee'
103
+ end
104
+ end
105
+
106
+ class Ruby192 < RubyVersion
107
+ include Component
108
+
109
+ desc "Latest stable version of Ruby 1.9"
110
+
111
+ key :ruby_192
112
+
113
+ belongs_to Environment
114
+
115
+ VERSION = '1.9.2'.freeze
116
+ PATCH_LEVEL = '290-r1'.freeze
117
+
118
+ def ruby_module
119
+ 'ruby19'
120
+ end
121
+
122
+ def mysql_adapter
123
+ 'mysql2'
124
+ end
125
+ end
126
+
127
+ class Ruby193 < RubyVersion
128
+ include Component
129
+
130
+ desc "Latest development release of Ruby 1.9"
131
+
132
+ key :ruby_193
133
+
134
+ belongs_to Environment
135
+
136
+ VERSION = '1.9.3'.freeze
137
+ PATCH_LEVEL = 'p0'.freeze
138
+ RUBYGEMS_VERSION = '1.8.11'.freeze
139
+
140
+ def ruby_version
141
+ "#{version}_#{patch_level}"
142
+ end
143
+
144
+ def ruby_module
145
+ 'ruby19'
146
+ end
147
+
148
+ def mysql_adapter
149
+ 'mysql2'
150
+ end
151
+ end
152
+
153
+ class JRuby < RubyVersion
154
+ NAME = 'JRuby'.freeze
155
+ VERSION = '1.6.5'.freeze
156
+ PATCH_LEVEL = nil
157
+ RUBYGEMS_VERSION = '1.5.1'.freeze
158
+
159
+ def self.label
160
+ "#{super} #{compat_version}"
161
+ end
162
+
163
+ def ruby_version
164
+ version
165
+ end
166
+
167
+ def ruby_flavor
168
+ 'dev-java/jruby-bin'
169
+ end
170
+
171
+ def ruby_module
172
+ 'rubyjruby16'
173
+ end
174
+ end
175
+
176
+ class JRuby187 < JRuby
177
+ include Component
178
+
179
+ desc "A Ruby runtime built on the JVM"
180
+
181
+ belongs_to Environment
182
+
183
+ key :jruby_187
184
+
185
+ def self.compat_version
186
+ '(ruby-1.8.7-p330)'
187
+ end
188
+ end
189
+
190
+ class JRuby192 < JRuby
191
+ include Component
192
+
193
+ desc "A Ruby runtime built on the JVM"
194
+
195
+ belongs_to Environment
196
+
197
+ key :jruby_192
198
+
199
+ def self.compat_version
200
+ '(ruby-1.9.2-p136)'
201
+ end
202
+ end
203
+
204
+ class Rubinius < RubyVersion
205
+ include Component
206
+
207
+ desc "A Ruby runtime written mostly in Ruby"
208
+
209
+ key :rubinius
210
+
211
+ belongs_to Environment
212
+
213
+ NAME = 'Rubinius'.freeze
214
+ VERSION = '1.2.4'.freeze
215
+ PATCH_LEVEL = nil
216
+
217
+ def ruby_version
218
+ version
219
+ end
220
+
221
+ def ruby_flavor
222
+ 'dev-lang/rubinius'
223
+ end
224
+
225
+ def ruby_module
226
+ 'rubyrbx12'
227
+ end
228
+
229
+ def mysql_adapter
230
+ 'mysql2'
231
+ end
232
+ end
233
+ end
234
+ end