servitor 0.0.1

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 (47) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +105 -0
  4. data/LICENSE +19 -0
  5. data/README.md +102 -0
  6. data/lib/cli/cli.rb +96 -0
  7. data/lib/configuration/configuration.rb +2 -0
  8. data/lib/configuration/configuration_resolver.rb +97 -0
  9. data/lib/configuration/yaml_configuration_provider.rb +28 -0
  10. data/lib/control/control.rb +0 -0
  11. data/lib/deployment/bundle_deployer.rb +14 -0
  12. data/lib/deployment/deployment.rb +2 -0
  13. data/lib/deployment/envdir_deployer.rb +34 -0
  14. data/lib/helpers/child_process_helper.rb +41 -0
  15. data/lib/helpers/helpers.rb +1 -0
  16. data/lib/infrastructure/infrastructure.rb +16 -0
  17. data/lib/infrastructure/infrastructure_provisioner.rb +25 -0
  18. data/lib/infrastructure/infrastructure_requirements.rb +25 -0
  19. data/lib/provisioners/Vagrantfile.erb +16 -0
  20. data/lib/provisioners/provisioners.rb +6 -0
  21. data/lib/provisioners/ssh_key.rb +22 -0
  22. data/lib/provisioners/vagrant_box.rb +116 -0
  23. data/lib/provisioners/vagrant_box_provisioner.rb +37 -0
  24. data/lib/provisioners/vagrant_box_ruby_installer.rb +34 -0
  25. data/lib/provisioners/vagrantfile.rb +34 -0
  26. data/lib/provisioners/veewee_box.rb +91 -0
  27. data/lib/resource/mysql_resource.rb +33 -0
  28. data/lib/resource/resource.rb +1 -0
  29. data/lib/service/service.rb +12 -0
  30. data/lib/service/service_definition/Servicefile.erb +54 -0
  31. data/lib/service/service_definition/deployment_stages.rb +16 -0
  32. data/lib/service/service_definition/resource_configuration.rb +14 -0
  33. data/lib/service/service_definition/service_configuration.rb +19 -0
  34. data/lib/service/service_definition/service_definition.rb +49 -0
  35. data/lib/service/service_definition/variable.rb +22 -0
  36. data/lib/service/service_file_parser.rb +21 -0
  37. data/lib/service/service_graph/service_graph.rb +58 -0
  38. data/lib/service/service_graph/service_graph_flattener.rb +34 -0
  39. data/lib/service/service_graph/service_graph_node.rb +15 -0
  40. data/lib/service/service_linker.rb +56 -0
  41. data/lib/service/service_locator.rb +43 -0
  42. data/lib/servitor.rb +47 -0
  43. data/servitor.gemspec +18 -0
  44. data/spec/provisioners/vagrant_basebox_provisioner_spec.rb +63 -0
  45. data/spec/provisioners/vagrant_box_ruby_provisioner_spec.rb +48 -0
  46. data/spec/spec_helper.rb +7 -0
  47. metadata +171 -0
@@ -0,0 +1,15 @@
1
+ module Servitor
2
+
3
+ class ServiceGraphNode
4
+
5
+ attr_reader :depends_on_nodes, :depended_on_by_nodes, :service_definition
6
+
7
+ def initialize(service_definition)
8
+ @service_definition = service_definition
9
+ @depends_on_nodes = []
10
+ @depended_on_by_nodes = []
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,56 @@
1
+ module Servitor
2
+ class ServiceLinker
3
+
4
+ attr_reader :service_nodes, :service_box_names
5
+
6
+ def initialize(service_nodes, service_box_names)
7
+ @service_nodes = service_nodes
8
+ @service_box_names = service_box_names
9
+ end
10
+
11
+ # Transforms the list of service nodes to a list of services. Service nodes
12
+ # describe the requirements and dependencies of each app, while services describe
13
+ # the VMs that satisfy those requirements and dependencies.
14
+ def link(options={})
15
+ next_ip = (options[:first_ip] || 2).to_i
16
+ next_port = (options[:first_port] || 3000).to_i
17
+ @service_nodes.map do |service_node|
18
+ service = Service.new
19
+ service.service_node = service_node
20
+ service.name = service_node.service_definition.name
21
+ service.box = @service_box_names[service_node]
22
+ service.ip_address = ip_address(next_ip, options)
23
+ begin
24
+ next_ip += 1
25
+ end while ip_address(next_ip, options) == host_ip(options)
26
+ service.forwarded_ports = { 80 => next_port }.merge(ports_for(service_node))
27
+ next_port += 1
28
+ service.root = service_node.service_definition.service_root
29
+ service.vm_root = options[:vm_root] || '/mnt/app/current'
30
+ service
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def ports_for(service_node)
37
+ ports = {}
38
+ if service_node.service_definition.configuration.resources.any? {|r| r.options[:type] == 'mysql'}
39
+ # ports[3306] = 3306
40
+ end
41
+ ports
42
+ end
43
+
44
+ def ip_block(options)
45
+ options[:ip_block] || '192.168.51'
46
+ end
47
+
48
+ def ip_address(next_ip, options)
49
+ "#{ip_block(options)}.#{next_ip}"
50
+ end
51
+
52
+ def host_ip(options)
53
+ "#{ip_block(options)}.1"
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,43 @@
1
+ module Servitor
2
+
3
+ class ServiceLocator
4
+
5
+ FILENAMES = %w(Servicefile .servicefile)
6
+ DEFAULT_SERVICES_DIR = ENV['SERVITOR_SERVICES_DIR'] || File.join(ENV['HOME'],'git')
7
+
8
+ class << self
9
+
10
+ attr_writer :services_dir
11
+
12
+ def services_dir
13
+ @services_dir || DEFAULT_SERVICES_DIR
14
+ end
15
+
16
+ # Locates the local service or a named service, returning a service config
17
+ def locate(service_name = nil)
18
+ if service_name
19
+ dir = File.join(services_dir, service_name)
20
+ else
21
+ dir = Dir.pwd
22
+ end
23
+ file = service_file_in_dir(dir)
24
+ ServiceFileParser.parse(file, dir)
25
+ end
26
+
27
+ private
28
+
29
+ def service_file_in_dir(dir)
30
+ file_names = FILENAMES + FILENAMES.map { |f| File.join('config', f) }
31
+ file_names.each do |file_name|
32
+ service_file_name = File.join(dir, file_name)
33
+ return service_file_name if File.exists?(service_file_name)
34
+ end
35
+ raise "No service file found in #{dir}"
36
+ end
37
+
38
+ end
39
+
40
+
41
+ end
42
+
43
+ end
data/lib/servitor.rb ADDED
@@ -0,0 +1,47 @@
1
+ module ServitorRequire
2
+ # for 1.8 compatibility
3
+ def servitor_require(path)
4
+ require(File.join(File.dirname(caller[0]), path))
5
+ end
6
+ end
7
+
8
+ extend(ServitorRequire)
9
+
10
+ servitor_require 'helpers/helpers'
11
+ servitor_require 'cli/cli'
12
+ servitor_require 'configuration/configuration'
13
+ servitor_require 'control/control'
14
+ servitor_require 'deployment/deployment'
15
+ servitor_require 'infrastructure/infrastructure'
16
+ servitor_require 'provisioners/provisioners'
17
+ servitor_require 'resource/resource'
18
+ servitor_require 'service/service'
19
+
20
+ module Servitor
21
+ def self.root
22
+ @root
23
+ end
24
+
25
+ def self.root=(path)
26
+ raise ServitorRootException, 'Servitor root has already been set; it can only be set once.' if @root
27
+ @root = path
28
+ end
29
+
30
+ def self.data_root
31
+ File.join(Servitor.root, '.servitor')
32
+ end
33
+
34
+ def self.boxes_root
35
+ File.join(Servitor.data_root, 'boxes')
36
+ end
37
+
38
+ def self.vagrantfile
39
+ File.join(Servitor.data_root, 'Vagrantfile')
40
+ end
41
+
42
+ def self.ssh_dir
43
+ File.join(Servitor.data_root, 'ssh')
44
+ end
45
+
46
+ class ServitorRootException < StandardError; end
47
+ end
data/servitor.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'servitor'
3
+ s.version = '0.0.1'
4
+ s.date = '2012-11-02'
5
+ s.summary = "A tool to help compose an SOA from 12-factor apps"
6
+ s.description = "A tool to help compose an SOA from 12-factor apps"
7
+ s.authors = ["Harry Wilkinson"]
8
+ s.email = 'hwilkinson@mdsol.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
11
+ s.homepage = 'http://github.com/harryw/servitor'
12
+
13
+ s.add_dependency 'veewee', '0.3.0.beta2'
14
+ s.add_dependency 'childprocess'
15
+ s.add_dependency 'erubis'
16
+ s.add_dependency 'mysql2'
17
+ s.add_development_dependency 'rspec'
18
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Servitor::VagrantBaseboxProvisioner do
4
+
5
+ before :all do
6
+ @requirements = Servitor::InfrastructureRequirements.new
7
+ @requirements.os_name 'ubuntu'
8
+ @requirements.os_version '10.04'
9
+ @requirements.os_arch '64'
10
+ @provisioner = Servitor::VagrantBaseboxProvisioner.new(@requirements)
11
+ end
12
+
13
+ describe '#name' do
14
+ it 'contains the os name and version' do
15
+ @provisioner.name.should == "#{@requirements.os_name}-#{@requirements.os_version}".gsub(/[^a-zA-Z0-9\-]/, '-')
16
+ end
17
+ end
18
+
19
+ describe '#provision' do
20
+
21
+ # The result of a #provision call is that there is a base box available satisfying the specified requirements.
22
+ # So, to test #provision we need to build a new box from that base and inspect it.
23
+
24
+ before :all do
25
+ @pwd = Dir.pwd
26
+ @provisioner.provision
27
+ @box = Servitor::VagrantBox.new('VagrantBaseBoxProvisionerTest')
28
+ @tmpdir = File.join(@pwd, 'VagrantBaseBoxProvisionerTest')
29
+ FileUtils.mkdir_p @tmpdir
30
+ FileUtils.cd @tmpdir
31
+ @box.init(@provisioner.name)
32
+ @box.up
33
+ end
34
+
35
+ after :all do
36
+ @box.destroy
37
+ FileUtils.cd @pwd
38
+ FileUtils.rm_rf @tmpdir
39
+ end
40
+
41
+ it 'has the requested OS' do
42
+ @box.ssh('lsb_release -si', :capture => true).should =~ Regexp.new(@requirements.os_name, true)
43
+ end
44
+
45
+ it 'has the requested OS version' do
46
+ @box.ssh('lsb_release -sr', :capture => true).should =~ Regexp.new(@requirements.os_version, true)
47
+ end
48
+
49
+ it 'has the requested OS architecture' do
50
+ arch = case @requirements.os_arch
51
+ when /64/
52
+ '64'
53
+ when /32/, /86/
54
+ '32'
55
+ else
56
+ raise "unrecognized architecture: #{@requirements.os_arch}"
57
+ end
58
+ @box.ssh("uname -m | sed 's/x86_//;s/i[3-6]86/32/'", :capture => true).should =~ Regexp.new(arch)
59
+ end
60
+
61
+ end
62
+
63
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Servitor::VagrantBoxRubyProvisioner do
4
+
5
+ before :all do
6
+ @requirements = Servitor::InfrastructureRequirements.new
7
+ @requirements.os_name 'ubuntu'
8
+ @requirements.os_version '10.04'
9
+ @requirements.os_arch '64'
10
+ @requirements.ruby_version '1.9.2'
11
+ @provisioner = Servitor::VagrantBoxRubyProvisioner.new(@requirements)
12
+ end
13
+
14
+ describe '#name' do
15
+ it 'contains the ruby version' do
16
+ @provisioner.name.should == "#{@requirements.os_name}-#{@requirements.os_version}-ruby-#{@requirements.ruby_version}".gsub(/[^a-zA-Z0-9\-]/, '-')
17
+ end
18
+ end
19
+
20
+ describe '#provision' do
21
+
22
+ # The result of a #provision call is that there is a base box available satisfying the specified requirements.
23
+ # So, to test #provision we need to build a new box from that base and inspect it.
24
+
25
+ before :all do
26
+ @pwd = Dir.pwd
27
+ @provisioner.provision
28
+ @box = Servitor::VagrantBox.new('VagrantBoxRubyProvisionerTest')
29
+ @tmpdir = File.join(@pwd, 'VagrantBoxRubyProvisionerTest')
30
+ FileUtils.mkdir_p @tmpdir
31
+ FileUtils.cd @tmpdir
32
+ @box.init(@provisioner.name)
33
+ @box.up
34
+ end
35
+
36
+ after :all do
37
+ @box.destroy
38
+ FileUtils.cd @pwd
39
+ FileUtils.rm_rf @tmpdir
40
+ end
41
+
42
+ it 'uses the requested ruby version' do
43
+ @box.ssh('ruby --version', :capture => true).should =~ Regexp.new(@requirements.ruby_version, true)
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../lib/servitor')
2
+
3
+ require 'rspec'
4
+
5
+ RSpec.configure do
6
+
7
+ end
metadata ADDED
@@ -0,0 +1,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: servitor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Harry Wilkinson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: veewee
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.3.0.beta2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.3.0.beta2
30
+ - !ruby/object:Gem::Dependency
31
+ name: childprocess
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: erubis
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mysql2
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: A tool to help compose an SOA from 12-factor apps
95
+ email: hwilkinson@mdsol.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - .gitignore
101
+ - Gemfile
102
+ - Gemfile.lock
103
+ - LICENSE
104
+ - README.md
105
+ - lib/cli/cli.rb
106
+ - lib/configuration/configuration.rb
107
+ - lib/configuration/configuration_resolver.rb
108
+ - lib/configuration/yaml_configuration_provider.rb
109
+ - lib/control/control.rb
110
+ - lib/deployment/bundle_deployer.rb
111
+ - lib/deployment/deployment.rb
112
+ - lib/deployment/envdir_deployer.rb
113
+ - lib/helpers/child_process_helper.rb
114
+ - lib/helpers/helpers.rb
115
+ - lib/infrastructure/infrastructure.rb
116
+ - lib/infrastructure/infrastructure_provisioner.rb
117
+ - lib/infrastructure/infrastructure_requirements.rb
118
+ - lib/provisioners/Vagrantfile.erb
119
+ - lib/provisioners/provisioners.rb
120
+ - lib/provisioners/ssh_key.rb
121
+ - lib/provisioners/vagrant_box.rb
122
+ - lib/provisioners/vagrant_box_provisioner.rb
123
+ - lib/provisioners/vagrant_box_ruby_installer.rb
124
+ - lib/provisioners/vagrantfile.rb
125
+ - lib/provisioners/veewee_box.rb
126
+ - lib/resource/mysql_resource.rb
127
+ - lib/resource/resource.rb
128
+ - lib/service/service.rb
129
+ - lib/service/service_definition/Servicefile.erb
130
+ - lib/service/service_definition/deployment_stages.rb
131
+ - lib/service/service_definition/resource_configuration.rb
132
+ - lib/service/service_definition/service_configuration.rb
133
+ - lib/service/service_definition/service_definition.rb
134
+ - lib/service/service_definition/variable.rb
135
+ - lib/service/service_file_parser.rb
136
+ - lib/service/service_graph/service_graph.rb
137
+ - lib/service/service_graph/service_graph_flattener.rb
138
+ - lib/service/service_graph/service_graph_node.rb
139
+ - lib/service/service_linker.rb
140
+ - lib/service/service_locator.rb
141
+ - lib/servitor.rb
142
+ - servitor.gemspec
143
+ - spec/provisioners/vagrant_basebox_provisioner_spec.rb
144
+ - spec/provisioners/vagrant_box_ruby_provisioner_spec.rb
145
+ - spec/spec_helper.rb
146
+ homepage: http://github.com/harryw/servitor
147
+ licenses: []
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.24
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: A tool to help compose an SOA from 12-factor apps
170
+ test_files: []
171
+ has_rdoc: