vito 0.0.4 → 0.0.5

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +11 -0
  3. data/README.md +32 -19
  4. data/Rakefile +5 -20
  5. data/bin/vito +1 -1
  6. data/lib/vito.rb +5 -1
  7. data/lib/vito/command_line/command.rb +21 -0
  8. data/lib/vito/command_line/document_flags.rb +30 -0
  9. data/lib/vito/command_line/options.rb +41 -0
  10. data/lib/vito/command_line/string.rb +35 -0
  11. data/lib/vito/commands/help.rb +62 -0
  12. data/lib/vito/commands/install.rb +17 -0
  13. data/lib/vito/core_ext/string.rb +33 -0
  14. data/lib/vito/dsl/installation.rb +5 -2
  15. data/lib/vito/dsl/server.rb +3 -3
  16. data/lib/vito/dsl_file.rb +11 -5
  17. data/lib/vito/operating_systems/ubuntu_10.rb +4 -0
  18. data/lib/vito/output.rb +3 -1
  19. data/lib/vito/recipe.rb +29 -4
  20. data/lib/vito/recipes/apache/install.rb +155 -0
  21. data/lib/vito/recipes/apache/service.rb +20 -0
  22. data/lib/vito/recipes/git/install.rb +39 -0
  23. data/lib/vito/recipes/passenger/install.rb +83 -0
  24. data/lib/vito/recipes/passenger/paths.rb +27 -0
  25. data/lib/vito/recipes/postgres/install.rb +106 -0
  26. data/lib/vito/recipes/rbenv/install.rb +54 -0
  27. data/lib/vito/recipes/ruby/install.rb +57 -0
  28. data/lib/vito/recipes/ruby/paths.rb +19 -0
  29. data/lib/vito/tasks/vagrant_bootstrap.rb +49 -0
  30. data/lib/vito/tests/vagrant_test_box.rb +44 -0
  31. data/lib/vito/utils/program_version.rb +2 -2
  32. data/lib/vito/version.rb +1 -1
  33. data/spec/acceptance/recipes/apache_acceptance_spec.rb +25 -0
  34. data/spec/acceptance/recipes/git_acceptance_spec.rb +11 -11
  35. data/spec/acceptance/recipes/postgres_acceptance_spec.rb +11 -11
  36. data/spec/acceptance/recipes/rbenv_acceptance_spec.rb +13 -13
  37. data/spec/acceptance/recipes/ruby_acceptance_spec.rb +15 -15
  38. data/spec/support/vagrant.rb +21 -16
  39. data/spec/vagrant_boxes/centos63/.gitkeep +0 -0
  40. data/{Vagrantfile → spec/vagrant_boxes/centos63/Vagrantfile} +5 -4
  41. data/spec/vagrant_boxes/ubuntu10/Vagrantfile +100 -0
  42. data/spec/vagrant_boxes/ubuntu12/Vagrantfile +100 -0
  43. data/spec/vito/command_line/command_spec.rb +20 -0
  44. data/spec/vito/command_line/options_spec.rb +50 -0
  45. data/spec/vito/command_line/string_spec.rb +32 -0
  46. data/spec/vito/commands/install_spec.rb +9 -0
  47. data/spec/vito/connection_spec.rb +2 -2
  48. data/spec/vito/core_ext/string_spec.rb +19 -0
  49. data/spec/vito/dsl/installation_spec.rb +2 -2
  50. data/spec/vito/dsl_file_spec.rb +56 -18
  51. data/spec/vito/output_spec.rb +2 -2
  52. data/spec/vito/recipe_spec.rb +53 -3
  53. data/spec/vito/recipes/apache/install_spec.rb +140 -0
  54. data/spec/vito/recipes/passenger/paths_spec.rb +18 -0
  55. data/spec/vito/recipes/ruby_spec.rb +5 -5
  56. data/spec/vito/tasks/vagrant_bootstrap_spec.rb +65 -0
  57. data/spec/vito/tests/vagrant_test_box_spec.rb +69 -0
  58. data/spec/vito/utils/program_version_spec.rb +4 -2
  59. data/templates/apache2/vito_site +12 -0
  60. data/vito.gemspec +1 -1
  61. data/vito.rb +7 -5
  62. metadata +53 -13
  63. data/lib/vito/recipes/git.rb +0 -37
  64. data/lib/vito/recipes/postgres.rb +0 -104
  65. data/lib/vito/recipes/rbenv.rb +0 -47
  66. data/lib/vito/recipes/ruby.rb +0 -43
  67. data/lib/vito/shell_initializer.rb +0 -21
  68. data/spec/vito/shell_initializer_spec.rb +0 -22
@@ -1,7 +1,7 @@
1
1
  module Vito
2
2
  module Dsl
3
3
  class Server
4
- def initialize(args = nil)
4
+ def initialize(args = [])
5
5
  @args = args
6
6
  end
7
7
 
@@ -9,8 +9,8 @@ module Vito
9
9
  @connection ||= Vito::Connection.new(type, options)
10
10
  end
11
11
 
12
- def install(name, options = {})
13
- Vito::Dsl::Installation.new(name, options, @connection).install
12
+ def install(name, options = {}, &block)
13
+ Vito::Dsl::Installation.new(name, options, @connection).install(&block)
14
14
  end
15
15
  end
16
16
  end
@@ -1,24 +1,30 @@
1
1
  module Vito
2
2
  class DslFile
3
- def initialize(argv = nil)
4
- @argv = argv
3
+ def initialize(command_line = nil)
4
+ @command_line = command_line
5
5
  end
6
6
 
7
- def run(code_string = nil, &block)
7
+ def run(string = nil, &block)
8
8
  if block_given?
9
9
  instance_eval(&block)
10
10
  else
11
- instance_eval(code_string)
11
+ string ||= vito_file
12
+ instance_eval(string)
12
13
  end
13
14
  end
14
15
 
15
16
  private
16
17
 
17
- attr_reader :options
18
+ attr_reader :command_line
18
19
 
19
20
  # called by the vito.rb file
20
21
  def server(*args, &block)
21
22
  Vito::Dsl::Server.new(args).instance_eval(&block)
22
23
  end
24
+
25
+ def vito_file
26
+ file = command_line.options.file || "vito.rb"
27
+ File.open(file).read
28
+ end
23
29
  end
24
30
  end
@@ -8,6 +8,10 @@ module Vito
8
8
  @connection = connection
9
9
  end
10
10
 
11
+ def service(service, command)
12
+ @connection.run("sudo /etc/init.d/#{service} #{command}")
13
+ end
14
+
11
15
  def is?(name, version = nil)
12
16
  version = VERSION unless version
13
17
  name == NAME && version.to_s == VERSION
@@ -12,7 +12,9 @@ module Vito
12
12
 
13
13
  def result
14
14
  if success?
15
- @result ||= @stdout.read
15
+ @result ||= @stdout
16
+ .read
17
+ .gsub(/(\n|\s){1,}\Z/, "")
16
18
  else
17
19
  @result ||= @stderr.read
18
20
  end
@@ -5,10 +5,35 @@ module Vito
5
5
  def initialize(options, connection)
6
6
  @options = options
7
7
  @connection = connection
8
+ @with = {}
8
9
  end
9
10
 
10
- def run
11
- raise "#{self.class.name} recipe needs to define a #run method"
11
+ def method_missing(name, args = {})
12
+ if with?(name.to_sym)
13
+ @with[name.to_sym]
14
+ else
15
+ raise "#{self.class.name} recipe needs to define a ##{name} method"
16
+ end
17
+ end
18
+
19
+ def with(name, args = {})
20
+ @with[name.to_sym] = args
21
+ end
22
+
23
+ def with?(name)
24
+ @with.keys.include?(name.to_sym)
25
+ end
26
+
27
+ def install
28
+ raise "#{self.class.name} recipe needs to define a #install method"
29
+ end
30
+
31
+ def remove
32
+ raise "#{self.class.name} recipe needs to define a #remove method"
33
+ end
34
+
35
+ def update
36
+ raise "#{self.class.name} recipe needs to define a #update method"
12
37
  end
13
38
 
14
39
  def depends_on_recipe(recipe, options = {})
@@ -34,9 +59,9 @@ module Vito
34
59
  @os ||= Vito::OperatingSystem.new(@connection).os
35
60
  end
36
61
 
37
- def install_os_dependencies
62
+ def install_os_dependencies(os_dependencies = nil)
38
63
  os.update_packages
39
- os.install_dependencies(os_dependencies) if self.respond_to?(:os_dependencies)
64
+ os.install_dependencies(os_dependencies) if os_dependencies
40
65
  end
41
66
  end
42
67
  end
@@ -0,0 +1,155 @@
1
+ module Vito
2
+ module Recipes
3
+ module Apache
4
+ class Install < Vito::Recipe
5
+ APACHE_HOMEDIR = "/etc/apache2"
6
+
7
+ def initialize(options, connection)
8
+ @vhosts = {}
9
+ super
10
+ end
11
+
12
+ def install
13
+ if installed?
14
+ Vito::Log.write "Apache2 already installed."
15
+ else
16
+ Vito::Log.write "Installing Apache2"
17
+ install_apache
18
+ end
19
+ end
20
+
21
+ # Used in the Apache block
22
+ def vhosts(options = {})
23
+ @vhosts[:rails_env] = options[:rails_env] || "production"
24
+ @vhosts[:servername] = options[:servername] || "www.example.com"
25
+
26
+ @vhosts[:ports] = options[:ports] || [80]
27
+ @vhosts[:ports] << 443 if Array(options[:with]).include?(:ssl)
28
+
29
+ @vhosts[:path] = options[:path]
30
+
31
+ raise InvalidApacheVhosts, "VHosts' app path not specified" unless @vhosts[:path]
32
+ raise InvalidApacheVhosts, "VHosts' app port not specified" unless @vhosts[:ports]
33
+ end
34
+
35
+ private
36
+
37
+ def installed?
38
+ false
39
+ end
40
+
41
+ def install_apache
42
+
43
+ # OS dependency
44
+ #
45
+ install_os_dependencies(os_dependencies)
46
+
47
+ # Install Apache
48
+ #
49
+ run_command "sudo apt-get install -y apache2 apache2-mpm-prefork apache2-prefork-dev"
50
+
51
+ # Install passenger
52
+ if with?(:passenger)
53
+ depends_on_recipe(:passenger, {server: :apache}.merge(passenger))
54
+ end
55
+
56
+ # CONFIGURES APACHE
57
+ #
58
+ # VHOSTS
59
+ #
60
+ unless @vhosts.empty?
61
+ Vito::Log.write("Setting up Apache's VHosts")
62
+
63
+ #
64
+ # For VHosts, create a file in /etc/apache2/sites-available/vito_site
65
+ #
66
+ # TODO: we shouldn't use Rails unless Passenger is specified
67
+ vhosts_template_file = if rails?
68
+ "vito_rails_site"
69
+ else
70
+ "vito_site"
71
+ end
72
+ created_vhosts = []
73
+
74
+ @vhosts[:ports].each do |port|
75
+ vhosts_file = "#{vhosts_template_file}_#{port}"
76
+
77
+ if site_already_enabled?(vhosts_file)
78
+ Vito::Log.write("#{vhosts_file} Apache site already defined.")
79
+ next
80
+ end
81
+ # Disable the old 000-default site
82
+ #
83
+ run_command "sudo a2dissite 000-default"
84
+
85
+
86
+ # Downloads template file
87
+ command = []
88
+ command << "cd #{APACHE_HOMEDIR}/sites-available/"
89
+ command << "sudo curl https://raw.github.com/kurko/vito/master/templates/apache2/#{vhosts_template_file} -O"
90
+ command << "sudo mv #{vhosts_template_file} #{vhosts_file}"
91
+ run_command command.join(" && ")
92
+
93
+ path = @vhosts[:path].gsub(/\//, '\/')
94
+ command = []
95
+ command << "cd #{APACHE_HOMEDIR}/sites-available/"
96
+ command << "sudo sed -i 's/{{VITO_PORT}}/#{port.to_i}/' #{vhosts_file}"
97
+ command << "sudo sed -i 's/{{VITO_SERVERNAME}}/#{@vhosts[:servername].gsub(/\//, "\/")}/' #{vhosts_file}"
98
+
99
+
100
+ # Rails specific
101
+ command << "sudo sed -i 's/{{VITO_RAILS_PUBLIC_PATH}}/#{path}/g' #{vhosts_file}"
102
+ command << "sudo sed -i 's/{{VITO_RAILS_ENV}}/#{@vhosts[:rails_env].gsub(/\//, "\/")}/' #{vhosts_file}"
103
+
104
+ # non-Rails
105
+ command << "sudo sed -i 's/{{VITO_SITE_PATH}}/#{path}/g' #{vhosts_file}"
106
+
107
+ run_command command.join(" && ")
108
+
109
+ created_vhosts << vhosts_file
110
+ end
111
+
112
+ # Replace the paths with whatever is passed in the vito.rb. Then create
113
+ # the path. Let's say it's /var/projects/, run:
114
+ #
115
+ # Considering the user 'deploy' and the group 'admin'
116
+ #
117
+ run_command "[ -d #{@vhosts[:path]} ] || sudo mkdir -p #{@vhosts[:path]}"
118
+ run_command "sudo chown \\$USER:admin #{@vhosts[:path]}"
119
+
120
+ Vito::Log.write("Activating Apache's VHosts")
121
+
122
+ command = []
123
+ created_vhosts.each do |file|
124
+ command << "sudo a2ensite #{file}"
125
+ end
126
+
127
+ if command.empty?
128
+ Vito::Log.write("*** No files to activate? ***")
129
+ else
130
+ run_command(command.join(" && "))
131
+ end
132
+ end
133
+
134
+ # Then restart apache
135
+ #
136
+ os.service(:apache2, :restart)
137
+
138
+ end
139
+
140
+ def os_dependencies
141
+ %w(libcurl4-openssl-dev curl)
142
+ end
143
+
144
+ def rails?
145
+ with?(:passenger)
146
+ end
147
+
148
+ def site_already_enabled?(site)
149
+ # TODO: apachectl is Ubuntu specific
150
+ query("sudo apachectl -S|grep site").result.match(/#{site}/)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,20 @@
1
+ module Vito
2
+ module Recipes
3
+ module Apache
4
+ class Service
5
+ def initialize(recipe)
6
+ @recipe = recipe
7
+ end
8
+
9
+ def restart
10
+
11
+
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :recipe
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,39 @@
1
+ module Vito
2
+ module Recipes
3
+ module Git
4
+ class Install < Vito::Recipe
5
+ def install
6
+ if git_installed?
7
+ Vito::Log.write "Git is already installed."
8
+ else
9
+ Vito::Log.write "Installing Git's OS dependencies"
10
+ install_os_dependencies(os_dependencies)
11
+ Vito::Log.write "Installing Git itself"
12
+ install_git
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def git_installed?
19
+ query("git --version").success?
20
+ end
21
+
22
+ def install_git
23
+ string = []
24
+ string << "sudo apt-get install -y git-core"
25
+ string << "git --version"
26
+ run_command(string.join(" && "))
27
+ end
28
+
29
+ def os_dependencies
30
+ %w(build-essential openssl libreadline6
31
+ libreadline6-dev zlib1g zlib1g-dev libssl-dev
32
+ libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3
33
+ libxml2-dev libxslt1-dev autoconf libc6-dev
34
+ libncurses5-dev)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,83 @@
1
+ module Vito
2
+ module Recipes
3
+ module Passenger
4
+ class Install < Vito::Recipe
5
+ class InvalidApacheVhosts < StandardError; end
6
+
7
+ def install
8
+ if installed?
9
+ Vito::Log.write "Passenger already installed."
10
+ else
11
+ Vito::Log.write "Installing Passenger"
12
+ depends_on_recipe(:ruby, dependent: "Passenger")
13
+
14
+ if @options[:server] == :apache
15
+ install_passenger_with_apache2
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def installed?
23
+ # TODO: apachectl is Ubuntu specific
24
+ query("sudo apachectl -M|grep passenger").result.match(/passenger_module/)
25
+ end
26
+
27
+ def install_passenger_with_apache2
28
+
29
+ run_command "gem install passenger && rbenv rehash"
30
+ run_command "passenger-install-apache2-module --auto"
31
+
32
+ paths = Paths.new(self)
33
+ mod_passenger = "LoadModule passenger_module #{paths.mod_passenger(:apache)}"
34
+ passenger_path = "PassengerRoot #{paths.passenger_path}"
35
+
36
+ ruby_paths = Vito::Recipes::Ruby::Paths.new(self)
37
+ ruby_path = "PassengerDefaultRuby #{ruby_paths.ruby_path}"
38
+
39
+ # Creates /etc/apache2/mods-available/passenger.load
40
+ #
41
+ passenger_load_file = "/etc/apache2/mods-available/passenger.load"
42
+
43
+ query "sudo rm #{passenger_load_file}"
44
+ command = ["sudo touch #{passenger_load_file}"]
45
+ command << "sudo echo #{mod_passenger} " + \
46
+ "| cat - #{passenger_load_file} > ~/vitotemp"
47
+ command << "sudo mv ~/vitotemp #{passenger_load_file}"
48
+
49
+ run_command command.join(" && ")
50
+
51
+ query "rm ~/vitofile"
52
+
53
+ # Creates /etc/apache2/mods-available/passenger.conf
54
+ #
55
+ passenger_conf_file = "/etc/apache2/mods-available/passenger.conf"
56
+
57
+ query "sudo rm #{passenger_conf_file}"
58
+ command = ["sudo touch #{passenger_conf_file}"]
59
+ command << "sudo echo #{passenger_path} " + \
60
+ "| cat - #{passenger_conf_file} > ~/vitotemp"
61
+ command << "sudo mv ~/vitotemp #{passenger_conf_file}"
62
+ command << "sudo echo #{ruby_path} " + \
63
+ "| cat - #{passenger_conf_file} > ~/vitotemp"
64
+ command << "sudo mv ~/vitotemp #{passenger_conf_file}"
65
+
66
+ run_command command.join(" && ")
67
+
68
+ query "rm ~/vitofile"
69
+
70
+ # Then active the module
71
+ #
72
+ run_command "sudo a2enmod passenger"
73
+ os.service(:apache2, :restart)
74
+
75
+ end
76
+
77
+ def os_dependencies
78
+ %w(build-essential libcurl4-openssl-dev curl)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,27 @@
1
+ module Vito
2
+ module Recipes
3
+ module Passenger
4
+ class Paths
5
+ def initialize(recipe)
6
+ @recipe = recipe
7
+ end
8
+
9
+ def passenger_path
10
+ @passenger_path ||= recipe.query("gem contents passenger|grep gemspec")
11
+ .result
12
+ .gsub(/\n/, "")
13
+ .gsub(/\/passenger\.gemspec/, "")
14
+ end
15
+
16
+ def mod_passenger(server = :apache)
17
+ server = "apache2" if server == :apache
18
+ "#{passenger_path}/buildout/#{server}/mod_passenger.so"
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :recipe
24
+ end
25
+ end
26
+ end
27
+ end