vito 0.0.2 → 0.0.4
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.
- 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
|