vito 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rvmrc +1 -0
- data/README.md +33 -7
- data/Rakefile +35 -0
- data/Vagrantfile +1 -1
- data/bin/vito +7 -2
- data/docs/manual.md +79 -0
- data/lib/samples/vito_for_rails.rb +14 -0
- data/lib/vito.rb +2 -2
- data/lib/vito/connection.rb +20 -27
- data/lib/vito/dsl/installation.rb +15 -0
- data/lib/vito/dsl/server.rb +17 -0
- data/lib/vito/dsl_file.rb +24 -0
- data/lib/vito/log.rb +7 -1
- data/lib/vito/operating_system.rb +1 -11
- data/lib/vito/operating_systems/ubuntu_10.rb +31 -0
- data/lib/vito/output.rb +21 -0
- data/lib/vito/recipe.rb +6 -3
- data/lib/vito/recipes/postgres.rb +104 -0
- data/lib/vito/recipes/rbenv.rb +10 -5
- data/lib/vito/shell_initializer.rb +7 -12
- data/lib/vito/version.rb +1 -1
- data/spec/acceptance/recipes/git_acceptance_spec.rb +20 -0
- data/spec/acceptance/recipes/postgres_acceptance_spec.rb +20 -0
- data/spec/acceptance/recipes/rbenv_acceptance_spec.rb +22 -0
- data/spec/acceptance/recipes/ruby_acceptance_spec.rb +24 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/vagrant.rb +34 -0
- data/spec/vito/connection_spec.rb +7 -4
- data/spec/vito/dsl/installation_spec.rb +17 -0
- data/spec/vito/dsl/server_spec.rb +0 -0
- data/spec/vito/dsl_file_spec.rb +37 -0
- data/spec/vito/log_spec.rb +10 -1
- data/spec/vito/operating_system_spec.rb +16 -0
- data/spec/vito/operating_systems/ubuntu_10_spec.rb +29 -0
- data/spec/vito/output_spec.rb +27 -5
- data/spec/vito/recipe_spec.rb +78 -0
- data/spec/vito/recipes/git_spec.rb +1 -1
- data/spec/vito/recipes/ruby_spec.rb +7 -35
- data/spec/vito/shell_initializer_spec.rb +10 -51
- data/vito.rb +3 -2
- metadata +33 -15
- data/lib/vito/installation.rb +0 -13
- data/lib/vito/logger.rb +0 -15
- data/lib/vito/recipes_configuration.rb +0 -11
- data/lib/vito/server.rb +0 -15
- data/lib/vito/ssh.rb +0 -62
- data/spec/contracts/vito/installation_contract.rb +0 -8
- data/spec/vito/installation_spec.rb +0 -25
- data/spec/vito/recipes_configuration_spec.rb +0 -7
- data/spec/vito/recipes_spec.rb +0 -9
data/lib/vito/output.rb
ADDED
@@ -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
|
-
|
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
|
data/lib/vito/recipes/rbenv.rb
CHANGED
@@ -22,18 +22,23 @@ module Vito
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def install_rbenv
|
25
|
-
puts "Installing
|
25
|
+
puts "Installing Rbenv..."
|
26
26
|
string = []
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
23
|
-
|
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
@@ -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
|
-
|
24
|
-
|
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
|