vito 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rvmrc +1 -0
  4. data/README.md +33 -7
  5. data/Rakefile +35 -0
  6. data/Vagrantfile +1 -1
  7. data/bin/vito +7 -2
  8. data/docs/manual.md +79 -0
  9. data/lib/samples/vito_for_rails.rb +14 -0
  10. data/lib/vito.rb +2 -2
  11. data/lib/vito/connection.rb +20 -27
  12. data/lib/vito/dsl/installation.rb +15 -0
  13. data/lib/vito/dsl/server.rb +17 -0
  14. data/lib/vito/dsl_file.rb +24 -0
  15. data/lib/vito/log.rb +7 -1
  16. data/lib/vito/operating_system.rb +1 -11
  17. data/lib/vito/operating_systems/ubuntu_10.rb +31 -0
  18. data/lib/vito/output.rb +21 -0
  19. data/lib/vito/recipe.rb +6 -3
  20. data/lib/vito/recipes/postgres.rb +104 -0
  21. data/lib/vito/recipes/rbenv.rb +10 -5
  22. data/lib/vito/shell_initializer.rb +7 -12
  23. data/lib/vito/version.rb +1 -1
  24. data/spec/acceptance/recipes/git_acceptance_spec.rb +20 -0
  25. data/spec/acceptance/recipes/postgres_acceptance_spec.rb +20 -0
  26. data/spec/acceptance/recipes/rbenv_acceptance_spec.rb +22 -0
  27. data/spec/acceptance/recipes/ruby_acceptance_spec.rb +24 -0
  28. data/spec/spec_helper.rb +10 -0
  29. data/spec/support/vagrant.rb +34 -0
  30. data/spec/vito/connection_spec.rb +7 -4
  31. data/spec/vito/dsl/installation_spec.rb +17 -0
  32. data/spec/vito/dsl/server_spec.rb +0 -0
  33. data/spec/vito/dsl_file_spec.rb +37 -0
  34. data/spec/vito/log_spec.rb +10 -1
  35. data/spec/vito/operating_system_spec.rb +16 -0
  36. data/spec/vito/operating_systems/ubuntu_10_spec.rb +29 -0
  37. data/spec/vito/output_spec.rb +27 -5
  38. data/spec/vito/recipe_spec.rb +78 -0
  39. data/spec/vito/recipes/git_spec.rb +1 -1
  40. data/spec/vito/recipes/ruby_spec.rb +7 -35
  41. data/spec/vito/shell_initializer_spec.rb +10 -51
  42. data/vito.rb +3 -2
  43. metadata +33 -15
  44. data/lib/vito/installation.rb +0 -13
  45. data/lib/vito/logger.rb +0 -15
  46. data/lib/vito/recipes_configuration.rb +0 -11
  47. data/lib/vito/server.rb +0 -15
  48. data/lib/vito/ssh.rb +0 -62
  49. data/spec/contracts/vito/installation_contract.rb +0 -8
  50. data/spec/vito/installation_spec.rb +0 -25
  51. data/spec/vito/recipes_configuration_spec.rb +0 -7
  52. data/spec/vito/recipes_spec.rb +0 -9
@@ -0,0 +1,21 @@
1
+ module Vito
2
+ class ConnectionOutput
3
+ def initialize(stdin, stdout, stderr, thread)
4
+ @stdout = stdout
5
+ @stderr = stderr
6
+ @thread = thread.value
7
+ end
8
+
9
+ def success?
10
+ @thread.exitstatus == 0
11
+ end
12
+
13
+ def result
14
+ if success?
15
+ @result ||= @stdout.read
16
+ else
17
+ @result ||= @stderr.read
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/vito/recipe.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  module Vito
2
+
3
+ # This is a parent class for recipes and shouldn't be used directly.
2
4
  class Recipe
3
5
  def initialize(options, connection)
4
6
  @options = options
@@ -10,7 +12,7 @@ module Vito
10
12
  end
11
13
 
12
14
  def depends_on_recipe(recipe, options = {})
13
- Installation.new(recipe, options, @connection).install
15
+ Dsl::Installation.new(recipe, options, @connection).install
14
16
  end
15
17
 
16
18
  def run_command(command)
@@ -28,10 +30,11 @@ module Vito
28
30
  Vito::Utils::ProgramVersion.new(version_command, @connection)
29
31
  end
30
32
 
31
- private
33
+ def os
34
+ @os ||= Vito::OperatingSystem.new(@connection).os
35
+ end
32
36
 
33
37
  def install_os_dependencies
34
- os = Vito::OperatingSystem.new(@connection)
35
38
  os.update_packages
36
39
  os.install_dependencies(os_dependencies) if self.respond_to?(:os_dependencies)
37
40
  end
@@ -0,0 +1,104 @@
1
+ module Vito
2
+ module Recipes
3
+ class Postgres < Vito::Recipe
4
+ def run
5
+ if installed?
6
+ Vito::Log.write "Postgres already installed."
7
+ else
8
+ Vito::Log.write "Installing Postgres"
9
+ install_os_dependencies
10
+ install
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def postgres_installed?
17
+ @memo ||= query("psql --version").success?
18
+ end
19
+
20
+ def user_exists?
21
+ query("sudo su - postgres -c \"psql -tAc \\\\\"SELECT 1 FROM pg_roles WHERE rolname='#{username}'\\\\\" | grep -q 1 || echo 'hey'\"").result == ""
22
+ end
23
+
24
+ def utf_template?
25
+ query("sudo su - postgres -c \"psql -d template1 -c \\\\\"SHOW SERVER_ENCODING;\\\\\" | grep -q UTF || echo 'hey'\"").result == ""
26
+ end
27
+
28
+ def installed?
29
+ # Only verifies Postgres configuration if it's installed
30
+ if postgres_installed?
31
+ Vito::Log.write "User doesn't exist. I will create one." unless user_exists?
32
+ Vito::Log.write "template1 database's encoding should be UTF-8. I'll adjust this." unless utf_template?
33
+ end
34
+
35
+ postgres_installed? &&
36
+ user_exists? &&
37
+ utf_template?
38
+ end
39
+
40
+ def username
41
+ "vitouser"
42
+ end
43
+
44
+ def password
45
+ "123456"
46
+ end
47
+
48
+ def install
49
+ string = []
50
+ run_command "sudo apt-get install -y postgresql-9.1 libpq-dev"
51
+
52
+ # Create user only if it doesn't exist yet
53
+ unless user_exists?
54
+ string << "sudo su - postgres -c \"createuser -d -r -s #{username}\""
55
+ end
56
+
57
+ run_command(string.join(" && ")) unless string.empty?
58
+ convert_template1_to_utf8 unless utf_template?
59
+ string = []
60
+
61
+ if os.is?(:ubuntu, "10")
62
+ string << "sudo /etc/init.d/postgresql restart"
63
+ else
64
+ string << "sudo service postgresql restart"
65
+ end
66
+ run_command "sudo su - postgres -c \"psql -d template1 -c \\\\\"alter user #{username} with password '#{password}'\\\\\";\""
67
+
68
+ run_command(string.join(" && "))
69
+ end
70
+
71
+ def install_os_dependencies
72
+ return if postgres_installed?
73
+ Vito::Log.write "Installing some OS dependencies first"
74
+ if os.is?(:ubuntu, "10")
75
+ run_command("sudo apt-get remove -y postgresql")
76
+ run_command("sudo apt-get autoremove -y")
77
+ run_command("sudo apt-get install -y python-software-properties")
78
+ run_command("sudo add-apt-repository ppa:pitti/postgresql && sudo apt-get update")
79
+ end
80
+
81
+ super
82
+ end
83
+
84
+ def os_dependencies
85
+ %w(libpq-dev postgresql-contrib)
86
+ end
87
+
88
+ def convert_template1_to_utf8
89
+ # In some cases, the OS locale won't be compatible with UTF-8. When
90
+ # creating a database, Rails will try to use Postgres' template1 with
91
+ # UTF-8.
92
+ #
93
+ # Here, we delete template1, then login in template0 to recreate
94
+ # template1 with UTF-8 encoding.
95
+ run_command "sudo su - postgres -c \"psql -d template1 -c \\\\\"UPDATE pg_database SET datallowconn = TRUE where datname = 'template0';\\\\\"\""
96
+ run_command "sudo su - postgres -c \"psql -d template0 -c \\\\\"UPDATE pg_database SET datistemplate = FALSE where datname = 'template1'; \\\\\"\""
97
+ run_command "sudo su - postgres -c \"psql -d template0 -c \\\\\"drop database template1; \\\\\"\""
98
+ run_command "sudo su - postgres -c \"psql -d template0 -c \\\\\"create database template1 with template = template0 encoding = 'UNICODE' LC_CTYPE = 'en_US.UTF-8' LC_COLLATE = 'C'; \\\\\"\""
99
+ run_command "sudo su - postgres -c \"psql -d template0 -c \\\\\" UPDATE pg_database SET datistemplate = TRUE where datname = 'template1'; \\\\\"\""
100
+ run_command "sudo su - postgres -c \"psql -d template1 -c \\\\\" UPDATE pg_database SET datallowconn = FALSE where datname = 'template0'; \\\\\"\""
101
+ end
102
+ end
103
+ end
104
+ end
@@ -22,18 +22,23 @@ module Vito
22
22
  end
23
23
 
24
24
  def install_rbenv
25
- puts "Installing rbenv..."
25
+ puts "Installing Rbenv..."
26
26
  string = []
27
- string << "git clone git://github.com/sstephenson/rbenv.git ~/.rbenv"
28
- string << "echo 'export PATH=\"\\$HOME/.rbenv/bin:\\$PATH\"' >> ~/.profile"
29
- string << "echo 'eval \"$(rbenv init -)\"' >> ~/.profile"
30
- string << "exec \\$SHELL -l"
27
+ # TODO verify if this folder already exists
28
+ run_command "git clone git://github.com/sstephenson/rbenv.git ~/.rbenv"
29
+
30
+ # TODO verify if .bashrc already have these lines
31
+ string = []
32
+ string << "echo 'eval \"$(rbenv init -)\"' | cat - ~/.bashrc > vitotemp && mv vitotemp ~/.bashrc"
33
+ string << "echo 'export PATH=\"\\$HOME/.rbenv/bin:\\$PATH\"' | cat - ~/.bashrc > vitotemp && mv vitotemp ~/.bashrc"
34
+
31
35
  run_command string.join(" && ")
32
36
  end
33
37
 
34
38
  def install_ruby_build
35
39
  puts "Installing ruby-build embedded into rbenv..."
36
40
  string = []
41
+ # TODO verify if this dir already exists
37
42
  string << "git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build"
38
43
  run_command string.join(" && ")
39
44
  end
@@ -2,25 +2,20 @@ require "vito/recipes/ruby"
2
2
 
3
3
  module Vito
4
4
  class ShellInitializer
5
- attr_reader :ssh
6
-
7
- def initialize(args)
8
- @installation_specs = File.open("vito.rb").read
5
+ def initialize(argv)
6
+ @argv = argv
9
7
  end
10
8
 
11
9
  def run
12
- run_vito_file
13
- end
14
-
15
- # called by the vito.rb file
16
- def server(*args, &block)
17
- Vito::Server.new.instance_eval &block
10
+ Vito::DslFile.new(argv).run(vito_file)
18
11
  end
19
12
 
20
13
  private
21
14
 
22
- def run_vito_file
23
- instance_eval @installation_specs
15
+ attr_reader :argv
16
+
17
+ def vito_file
18
+ File.open("vito.rb").read
24
19
  end
25
20
  end
26
21
  end
data/lib/vito/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Vito
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe "Git recipe" do
4
+ before do
5
+ setup_vagrant
6
+ end
7
+
8
+ it "installs Git" do
9
+ assert_installation("git --version").should be_false
10
+
11
+ Vito::DslFile.new.run do
12
+ server do
13
+ connection :ssh, command: 'ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222', silent: true
14
+ install :git
15
+ end
16
+ end
17
+
18
+ assert_installation("git --version").should be_true
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require "spec_helper"
2
+
3
+ describe "Postgres recipe" do
4
+ before do
5
+ setup_vagrant
6
+ end
7
+
8
+ it "installs Postgres" do
9
+ assert_installation("psql --version").should be_false
10
+
11
+ Vito::DslFile.new.run do
12
+ server do
13
+ connection :ssh, command: 'ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222', silent: true
14
+ install :postgres
15
+ end
16
+ end
17
+
18
+ assert_installation("psql --version").should be_true
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe "Rbenv recipe" do
4
+ before do
5
+ setup_vagrant
6
+ end
7
+
8
+ it "installs Git and then Rbenv" do
9
+ assert_installation("git --version").should be_false
10
+ assert_installation("rbenv --version").should be_false
11
+
12
+ Vito::DslFile.new.run do
13
+ server do
14
+ connection :ssh, command: 'ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222', silent: true
15
+ install :rbenv
16
+ end
17
+ end
18
+
19
+ assert_installation("git --version").should be_true
20
+ assert_installation("rbenv --version").should be_true
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe "Ruby recipe" do
4
+ before do
5
+ setup_vagrant
6
+ end
7
+
8
+ it "installs Git, Rbenv and then Ruby" do
9
+ assert_installation("git --version").should be_false
10
+ assert_installation("rbenv --version").should be_false
11
+ assert_installation("ruby -v").should be_false
12
+
13
+ Vito::DslFile.new.run do
14
+ server do
15
+ connection :ssh, command: 'ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222', silent: true
16
+ install :ruby, version: "1.9.3-p125"
17
+ end
18
+ end
19
+
20
+ assert_installation("git --version").should be_true
21
+ assert_installation("rbenv --version").should be_true
22
+ assert_installation("ruby -v").should be_true
23
+ end
24
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,12 @@
1
+ ENV["env"] ||= "test"
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
1
3
  require "rubygems"
2
4
  require "bundler/setup"
5
+ require "open3"
6
+ require "vito"
7
+
8
+ Dir["./spec/support/*.rb"].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ config.include RSpecSupport::Vagrant
12
+ end
@@ -0,0 +1,34 @@
1
+ module RSpecSupport
2
+ module Vagrant
3
+ def connection
4
+ 'ssh -i ~/.vagrant.d/insecure_private_key vagrant@localhost -p2222'
5
+ end
6
+
7
+ def setup_vagrant
8
+ system_command("vagrant up")
9
+ raise "Box not working" unless vagrant_command("ls")
10
+ reboot_vagrant_box
11
+ end
12
+
13
+ def assert_installation(command)
14
+ vagrant_command(command)
15
+ end
16
+
17
+ def reboot_vagrant_box
18
+ system_command("vagrant snapshot go initial_box")
19
+ end
20
+
21
+ private
22
+
23
+ def system_command(command)
24
+ stdin, stdout, stderr, thread = Open3.popen3(command)
25
+ thread.value.exitstatus == 0
26
+ end
27
+
28
+ def vagrant_command(command)
29
+ command = "#{connection} #{command}"
30
+ stdin, stdout, stderr, thread = Open3.popen3(command)
31
+ thread.value.exitstatus == 0
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,4 @@
1
1
  require "spec_helper"
2
- require "vito/connection"
3
- require "vito/log"
4
2
 
5
3
  describe Vito::Connection do
6
4
  before do
@@ -20,8 +18,13 @@ describe Vito::Connection do
20
18
  context "invalid command" do
21
19
  let(:command) { "harrr" }
22
20
 
23
- its(:success?) { should be_false }
24
- its(:result) { should == "sh: harrr: command not found\n" }
21
+ it "raises error and logs its messages" do
22
+ Vito::Log.should_receive(:raise).with("An error occurred. Here's the stacktrace:")
23
+ Vito::Log.should_receive(:raise).with("sh: harrr: command not found\n")
24
+ Vito::Log.stub(:raise)
25
+
26
+ expect{ subject }.to raise_error "Error."
27
+ end
25
28
  end
26
29
  end
27
30
  end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe Vito::Dsl::Installation do
4
+ let(:connection) { double }
5
+ let(:ruby) { double }
6
+ let(:options) { {version: "2.0.0"} }
7
+
8
+ subject { described_class.new(:ruby, options, connection) }
9
+
10
+ describe "#install" do
11
+ it "installs each recipes" do
12
+ ruby.should_receive(:run)
13
+ Vito::Recipes::Ruby.stub(:new).with(options, connection) { ruby }
14
+ subject.install
15
+ end
16
+ end
17
+ end
File without changes
@@ -0,0 +1,37 @@
1
+ require "vito/dsl_file"
2
+
3
+ describe Vito::DslFile do
4
+ let(:server) { double }
5
+
6
+ subject { described_class.new }
7
+
8
+ before do
9
+ stub_const("Vito::Dsl::Server", Class.new)
10
+ end
11
+
12
+ describe "#run" do
13
+ before do
14
+ Vito::Dsl::Server.stub(:new).with([:hey]) { server }
15
+ end
16
+
17
+ it "runs the server block evaluating it as string" do
18
+ server.should_receive(:instance_eval)
19
+
20
+ subject.run <<-str
21
+ server :hey do
22
+
23
+ end
24
+ str
25
+ end
26
+
27
+ it "runs the server as a Ruby block" do
28
+ server.should_receive(:instance_eval)
29
+
30
+ subject.run do
31
+ server :hey do
32
+
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end