ruby_yacht 0.1.0
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 +7 -0
- data/.codeclimate.yml +27 -0
- data/.gitignore +4 -0
- data/.rdoc_options +29 -0
- data/.rspec +1 -0
- data/.rubocop.yml +1156 -0
- data/.travis.yml +4 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +8 -0
- data/README.md +216 -0
- data/doc/CONTRIBUTING.md +12 -0
- data/doc/TODO.md +28 -0
- data/doc/configuration_sample.rb +87 -0
- data/lib/ruby_yacht/dsl/app.rb +59 -0
- data/lib/ruby_yacht/dsl/configuration.rb +55 -0
- data/lib/ruby_yacht/dsl/database.rb +57 -0
- data/lib/ruby_yacht/dsl/dns_server.rb +38 -0
- data/lib/ruby_yacht/dsl/dsl.rb +252 -0
- data/lib/ruby_yacht/dsl/project.rb +140 -0
- data/lib/ruby_yacht/dsl.rb +6 -0
- data/lib/ruby_yacht/images/app/Dockerfile.erb +32 -0
- data/lib/ruby_yacht/images/app/checkout.rb +7 -0
- data/lib/ruby_yacht/images/app/startup.rb +17 -0
- data/lib/ruby_yacht/images/app/update_database_config.rb +45 -0
- data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +23 -0
- data/lib/ruby_yacht/images/app-dependencies/install_gems.rb +12 -0
- data/lib/ruby_yacht/images/database/Dockerfile.erb +26 -0
- data/lib/ruby_yacht/images/database/load_seeds.rb +42 -0
- data/lib/ruby_yacht/images/database/setup.rb +19 -0
- data/lib/ruby_yacht/images/database/setup_database.sql.erb +12 -0
- data/lib/ruby_yacht/images/deploy/Dockerfile.erb +2 -0
- data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -0
- data/lib/ruby_yacht/images/web/add_app.rb +12 -0
- data/lib/ruby_yacht/images/web/add_project.rb +14 -0
- data/lib/ruby_yacht/images/web/app_config.erb +11 -0
- data/lib/ruby_yacht/images/web/index.html.erb +10 -0
- data/lib/ruby_yacht/images/web/index_config.erb +12 -0
- data/lib/ruby_yacht/images/web/setup.rb +22 -0
- data/lib/ruby_yacht/runner/build.rb +21 -0
- data/lib/ruby_yacht/runner/build_images.rb +82 -0
- data/lib/ruby_yacht/runner/checkout.rb +68 -0
- data/lib/ruby_yacht/runner/command.rb +161 -0
- data/lib/ruby_yacht/runner/help.rb +55 -0
- data/lib/ruby_yacht/runner/implode.rb +33 -0
- data/lib/ruby_yacht/runner/run_containers.rb +105 -0
- data/lib/ruby_yacht/runner/runner.rb +42 -0
- data/lib/ruby_yacht/runner/services.rb +79 -0
- data/lib/ruby_yacht/runner/shell.rb +66 -0
- data/lib/ruby_yacht/runner/update_hosts.rb +72 -0
- data/lib/ruby_yacht/runner.rb +18 -0
- data/lib/ruby_yacht.rb +6 -0
- data/ruby_yacht.gemspec +18 -0
- data/spec/docker/Dockerfile +5 -0
- data/spec/docker/build.bash +10 -0
- data/spec/dsl/app_spec.rb +47 -0
- data/spec/dsl/configuration_spec.rb +64 -0
- data/spec/dsl/database_spec.rb +75 -0
- data/spec/dsl/dns_server_spec.rb +25 -0
- data/spec/dsl/dsl_spec.rb +298 -0
- data/spec/dsl/project_spec.rb +266 -0
- data/spec/fixtures/app-dependencies-dockerfile +25 -0
- data/spec/fixtures/database-dockerfile +31 -0
- data/spec/fixtures/deploy-dockerfile +2 -0
- data/spec/fixtures/mars-dockerfile +32 -0
- data/spec/fixtures/multi-project-web-dockerfile +35 -0
- data/spec/fixtures/web-dockerfile +27 -0
- data/spec/runner/build_images_spec.rb +164 -0
- data/spec/runner/build_spec.rb +86 -0
- data/spec/runner/checkout_spec.rb +128 -0
- data/spec/runner/command_spec.rb +94 -0
- data/spec/runner/help_spec.rb +73 -0
- data/spec/runner/implode_spec.rb +62 -0
- data/spec/runner/run_containers_spec.rb +141 -0
- data/spec/runner/runner_spec.rb +117 -0
- data/spec/runner/services_spec.rb +135 -0
- data/spec/runner/shell_spec.rb +123 -0
- data/spec/runner/update_hosts_spec.rb +163 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/docker_stubbing.rb +93 -0
- data/spec/support/test_project.rb +56 -0
- metadata +193 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::RunContainers do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'run_containers' }
|
8
|
+
specify { expect(described_class.description).to eq 'Runs containers for all the apps' }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "run behavior" do
|
12
|
+
before do
|
13
|
+
allow(subject).to receive(:remove_container)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "runs the containers for all the apps" do
|
17
|
+
docker.fail_unexpected_commands!
|
18
|
+
docker.expect 'run -d --net=apollo --net-alias=apollo-mars --name=apollo-mars apollo-mars'
|
19
|
+
docker.expect 'run -d --net=apollo --net-alias=apollo-saturn --name=apollo-saturn apollo-saturn'
|
20
|
+
docker.expect 'run -d -p 80:80 --net=apollo --net-alias=apollo-web --name=apollo-web apollo-web'
|
21
|
+
subject.run
|
22
|
+
end
|
23
|
+
|
24
|
+
it "tries to remove all the containers" do
|
25
|
+
subject.run
|
26
|
+
expect(subject).to have_received(:remove_container).with('apollo-mars')
|
27
|
+
expect(subject).to have_received(:remove_container).with('apollo-saturn')
|
28
|
+
expect(subject).to have_received(:remove_container).with('apollo-web')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns true" do
|
32
|
+
expect(subject.run).to be_truthy
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with a deploy container" do
|
36
|
+
before do
|
37
|
+
RubyYacht.configuration.projects.first.create_deploy_container = true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "runs the deploy container" do
|
41
|
+
docker.expect 'run -d -it --net=apollo --net-alias=apollo-deploy --name=apollo-deploy apollo-deploy'
|
42
|
+
subject.run
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns true" do
|
46
|
+
expect(subject.run).to be_truthy
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a local database" do
|
51
|
+
before do
|
52
|
+
RubyYacht.configuration.projects.first.database.host = 'localhost'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "runs the database container" do
|
56
|
+
docker.expect 'run -d --net=apollo --net-alias=apollo-database --name=apollo-database apollo-database'
|
57
|
+
subject.run
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns true" do
|
61
|
+
expect(subject.run).to be_truthy
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with multiple projects" do
|
66
|
+
before do
|
67
|
+
RubyYacht.configure_second_test_project
|
68
|
+
end
|
69
|
+
|
70
|
+
it "runs the containers for both projects" do
|
71
|
+
docker.fail_unexpected_commands!
|
72
|
+
docker.expect 'run -d --net=apollo --net-alias=apollo-mars --name=apollo-mars apollo-mars'
|
73
|
+
docker.expect 'run -d --net=apollo --net-alias=apollo-saturn --name=apollo-saturn apollo-saturn'
|
74
|
+
docker.expect 'run -d --net=apollo --net-alias=jupiter-venus --name=jupiter-venus jupiter-venus'
|
75
|
+
docker.expect 'run -d --net=apollo --net-alias=jupiter-saturn --name=jupiter-saturn jupiter-saturn'
|
76
|
+
docker.expect 'run -d -p 80:80 --net=apollo --net-alias=apollo-web --name=apollo-web apollo-web'
|
77
|
+
subject.run
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns true" do
|
81
|
+
expect(subject.run).to be_truthy
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "with DNS server config" do
|
86
|
+
before do
|
87
|
+
project = RubyYacht.configuration.projects.first
|
88
|
+
project.dns_server = RubyYacht::DnsServer.new
|
89
|
+
project.dns_server.servers = ['8.10.1.1', '8.10.1.2']
|
90
|
+
project.dns_server.search_domains = ['apps.test.com', 'db.test.com']
|
91
|
+
end
|
92
|
+
|
93
|
+
it "gives the DNS information to the docker container" do
|
94
|
+
docker.expect 'run -d --dns=8.10.1.1 --dns=8.10.1.2 --dns-search=apps.test.com --dns-search=db.test.com --net=apollo --net-alias=apollo-mars --name=apollo-mars apollo-mars'
|
95
|
+
subject.run
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns true" do
|
99
|
+
expect(subject.run).to be_truthy
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when checking out the code locally" do
|
104
|
+
before do
|
105
|
+
RubyYacht.configuration.projects.first.check_out_locally = true
|
106
|
+
end
|
107
|
+
|
108
|
+
it "maps the code volume to a local directory" do
|
109
|
+
docker.expect 'run -d -v $PWD/../code/mars:/var/code --net=apollo --net-alias=apollo-mars --name=apollo-mars apollo-mars'
|
110
|
+
docker.expect 'run -d -v $PWD/../code/saturn:/var/code --net=apollo --net-alias=apollo-saturn --name=apollo-saturn apollo-saturn'
|
111
|
+
subject.run
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns true" do
|
115
|
+
expect(subject.run).to be_truthy
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when creating a deploy container" do
|
119
|
+
before do
|
120
|
+
RubyYacht.configuration.projects.first.create_deploy_container = true
|
121
|
+
end
|
122
|
+
it "maps the code volume to a local directory" do
|
123
|
+
docker.expect 'run -d -v $PWD/../code:/var/code -it --net=apollo --net-alias=apollo-deploy --name=apollo-deploy apollo-deploy'
|
124
|
+
subject.run
|
125
|
+
end
|
126
|
+
|
127
|
+
it "returns true" do
|
128
|
+
expect(subject.run).to be_truthy
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "remove_container" do
|
135
|
+
it "sends the command to docker" do
|
136
|
+
allow(IO).to receive(:popen)
|
137
|
+
subject.remove_container('apollo-mars')
|
138
|
+
expect(IO).to have_received(:popen).with('docker rm -f apollo-mars', err: :close)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner do
|
4
|
+
before do
|
5
|
+
allow(described_class).to receive(:puts)
|
6
|
+
allow(described_class).to receive(:exit)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "commands" do
|
10
|
+
it "contains all the defined commands" do
|
11
|
+
commands = ObjectSpace.each_object(Class).select { |klass| klass < RubyYacht::Runner::Command && klass.inspect =~ /^RubyYacht::Runner/ }.uniq
|
12
|
+
expect(described_class.commands.sort_by(&:name)).to eq commands.sort_by(&:name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "arguments" do
|
17
|
+
it "gets the command-line arguments" do
|
18
|
+
expect(described_class.arguments).to eq ARGV
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "run" do
|
23
|
+
let(:command) { RubyYacht::Runner::Checkout.new }
|
24
|
+
before do
|
25
|
+
allow(described_class).to receive(:arguments).and_return %w(checkout -p apollo mars issue1234)
|
26
|
+
allow(command).to receive(:run)
|
27
|
+
allow(RubyYacht::Runner::Checkout).to receive(:new).and_return(command)
|
28
|
+
RubyYacht.configure_test_project
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a valid command" do
|
32
|
+
context "with a successful command" do
|
33
|
+
before do
|
34
|
+
allow(command).to receive(:run).and_return(true)
|
35
|
+
described_class.run
|
36
|
+
end
|
37
|
+
|
38
|
+
it "calls the command" do
|
39
|
+
expect(command.project_name).to eq :apollo
|
40
|
+
expect(command.app).to eq 'mars'
|
41
|
+
expect(command.branch).to eq 'issue1234'
|
42
|
+
expect(command).to have_received(:run)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does not exit" do
|
46
|
+
expect(described_class).not_to have_received(:exit)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "with a failed command" do
|
51
|
+
before do
|
52
|
+
allow(command).to receive(:run).and_return(false)
|
53
|
+
described_class.run
|
54
|
+
end
|
55
|
+
|
56
|
+
it "calls the command" do
|
57
|
+
expect(command).to have_received(:run)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "exits with a failure code" do
|
61
|
+
expect(described_class).to have_received(:exit).with(1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with a nil command" do
|
67
|
+
before do
|
68
|
+
allow(described_class).to receive(:arguments).and_return []
|
69
|
+
described_class.run
|
70
|
+
end
|
71
|
+
|
72
|
+
it "logs a message" do
|
73
|
+
invocation = $0
|
74
|
+
expect(described_class).to have_received(:puts).with("You must provide a command to run")
|
75
|
+
expect(described_class).to have_received(:puts).with("Run `#{invocation} help` for more information")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "exits with a failure code" do
|
79
|
+
expect(described_class).to have_received(:exit).with(1)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "with a blank command" do
|
84
|
+
before do
|
85
|
+
allow(described_class).to receive(:arguments).and_return ['']
|
86
|
+
described_class.run
|
87
|
+
end
|
88
|
+
|
89
|
+
it "logs a message" do
|
90
|
+
invocation = $0
|
91
|
+
expect(described_class).to have_received(:puts).with("You must provide a command to run")
|
92
|
+
expect(described_class).to have_received(:puts).with("Run `#{invocation} help` for more information")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "exits with a failure code" do
|
96
|
+
expect(described_class).to have_received(:exit).with(1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "with an invalid command" do
|
101
|
+
before do
|
102
|
+
allow(described_class).to receive(:arguments).and_return %w(foo bar)
|
103
|
+
described_class.run
|
104
|
+
end
|
105
|
+
|
106
|
+
it "logs a message" do
|
107
|
+
invocation = $0
|
108
|
+
expect(described_class).to have_received(:puts).with("Command not recognized: foo")
|
109
|
+
expect(described_class).to have_received(:puts).with("Run `#{invocation} help` for more information")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "exits with a failure code" do
|
113
|
+
expect(described_class).to have_received(:exit).with(1)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Services do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'services' }
|
8
|
+
specify { expect(described_class.description).to eq 'Start, stop, or restart containers' }
|
9
|
+
|
10
|
+
it "has a banner with more information about the command" do
|
11
|
+
usage = "Usage: rspec services [COMMAND]"
|
12
|
+
usage += "\n\nStart, stop, or restart containers"
|
13
|
+
usage += "\n\n[COMMAND] is required, and can be start, stop, or restart"
|
14
|
+
expect(subject.option_parser.banner).to eq usage
|
15
|
+
end
|
16
|
+
|
17
|
+
it "gets the command from position arguments" do
|
18
|
+
subject.parse_positional_arguments(["restart", "foo"])
|
19
|
+
expect(subject.command).to eq 'restart'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "run behavior" do
|
24
|
+
before do
|
25
|
+
subject.command = 'stop'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sends the command to each container" do
|
29
|
+
docker.fail_unexpected_commands!
|
30
|
+
docker.expect 'stop apollo-mars'
|
31
|
+
docker.expect 'stop apollo-saturn'
|
32
|
+
docker.expect 'stop apollo-web'
|
33
|
+
subject.run
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns true" do
|
37
|
+
expect(subject.run).to be_truthy
|
38
|
+
end
|
39
|
+
|
40
|
+
context "with a local database" do
|
41
|
+
before do
|
42
|
+
RubyYacht.configuration.projects.first.database.host = 'localhost'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "stops the database" do
|
46
|
+
docker.expect 'stop apollo-database'
|
47
|
+
subject.run
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns true" do
|
51
|
+
expect(subject.run).to be_truthy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with a docker machine" do
|
56
|
+
before do
|
57
|
+
allow(subject).to receive(:backtick).with('which docker-machine').and_return '/usr/bin/docker-machine'
|
58
|
+
allow(subject).to receive(:backtick).with('docker-machine env default').and_return "# Test\nexport TEST_VAL=\"123\""
|
59
|
+
ENV.delete('TEST_VAL')
|
60
|
+
end
|
61
|
+
|
62
|
+
after do
|
63
|
+
ENV.delete('TEST_VAL')
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with the start command" do
|
67
|
+
before do
|
68
|
+
subject.command = 'start'
|
69
|
+
end
|
70
|
+
|
71
|
+
it "starts the docker machine" do
|
72
|
+
subject.run
|
73
|
+
expect(@system_commands).to eq ['docker-machine start default']
|
74
|
+
expect(ENV['TEST_VAL']).to eq '123'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns true" do
|
78
|
+
expect(subject.run).to be_truthy
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with the stop command" do
|
83
|
+
before do
|
84
|
+
subject.command = 'stop'
|
85
|
+
end
|
86
|
+
|
87
|
+
it "does not send a message to docker machine" do
|
88
|
+
subject.run
|
89
|
+
expect(@system_commands).to eq []
|
90
|
+
expect(ENV['TEST_VAL']).to be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns true" do
|
94
|
+
expect(subject.run).to be_truthy
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "with no command" do
|
100
|
+
before do
|
101
|
+
subject.command = nil
|
102
|
+
end
|
103
|
+
|
104
|
+
it "logs error messages" do
|
105
|
+
subject.run
|
106
|
+
expect(@log_entries).to eq [
|
107
|
+
"You must provide a command",
|
108
|
+
"Run rspec help services for more information"
|
109
|
+
]
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns false" do
|
113
|
+
expect(subject.run).to be_falsey
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "with an invalid command" do
|
118
|
+
before do
|
119
|
+
subject.command = 'foo'
|
120
|
+
end
|
121
|
+
|
122
|
+
it "logs error messages" do
|
123
|
+
subject.run
|
124
|
+
expect(@log_entries).to eq [
|
125
|
+
"foo is not a valid docker command",
|
126
|
+
"Run rspec help services for more information"
|
127
|
+
]
|
128
|
+
end
|
129
|
+
|
130
|
+
it "returns false" do
|
131
|
+
expect(subject.run).to be_falsey
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RubyYacht::Runner::Shell do
|
4
|
+
include DockerCommandSpec
|
5
|
+
|
6
|
+
describe "command information" do
|
7
|
+
specify { expect(described_class.command).to eq 'shell' }
|
8
|
+
specify { expect(described_class.description).to eq 'Open a shell in a container' }
|
9
|
+
|
10
|
+
describe "option parser" do
|
11
|
+
it "has the usage banner" do
|
12
|
+
expect(subject.option_parser.banner).to eq "Usage: rspec shell [options] [APP] [command]"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has the usage summary" do
|
16
|
+
usage = ["\n"]
|
17
|
+
usage << "The command is optional. If you omit it, this will open a bash shell\n"
|
18
|
+
usage << "\n"
|
19
|
+
usage << "Options:\n"
|
20
|
+
usage << " -p, --project PROJECT The project with the app we are opening the sell in. Default: apollo\n"
|
21
|
+
expect(subject.option_parser.summarize).to eq usage
|
22
|
+
end
|
23
|
+
|
24
|
+
it "takes the project from the command line" do
|
25
|
+
arguments = ["-p", "jupiter", "venus"]
|
26
|
+
subject.option_parser.parse!(arguments)
|
27
|
+
expect(subject.project_name).to eq :jupiter
|
28
|
+
expect(arguments).to eq ["venus"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "parse_positional_arguments" do
|
33
|
+
it "takes the app from the command line" do
|
34
|
+
subject.parse_positional_arguments(["venus", "rails", "c"])
|
35
|
+
expect(subject.app).to eq "venus"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "takes the command from the command line" do
|
39
|
+
subject.parse_positional_arguments(["venus", "rails", "c"])
|
40
|
+
expect(subject.command).to eq "rails c"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "defaults the command to bash" do
|
44
|
+
subject.parse_positional_arguments(["venus"])
|
45
|
+
expect(subject.command).to eq "bash"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "run behavior" do
|
51
|
+
before do
|
52
|
+
subject.app = 'saturn'
|
53
|
+
subject.command = 'rails c'
|
54
|
+
RubyYacht.configure_second_test_project
|
55
|
+
allow(subject).to receive :exec
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "default_project" do
|
59
|
+
it "is the first project defined" do
|
60
|
+
expect(subject.default_project.name).to eq :apollo
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "opens the shell in docker" do
|
65
|
+
subject.run
|
66
|
+
expect(subject).to have_received(:exec).with("docker exec -it apollo-saturn bash -c 'cd /var/code; TERM=xterm rails c'")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns true" do
|
70
|
+
expect(subject.run).to be_truthy
|
71
|
+
end
|
72
|
+
|
73
|
+
context "with no app" do
|
74
|
+
before do
|
75
|
+
subject.app = nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "logs an error" do
|
79
|
+
subject.run
|
80
|
+
expect(@log_entries).to eq [
|
81
|
+
"You must provide an app name",
|
82
|
+
"Run rspec help shell for more information"
|
83
|
+
]
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns false" do
|
87
|
+
expect(subject.run).to be_falsey
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with a specific project" do
|
92
|
+
before do
|
93
|
+
subject.project_name = :jupiter
|
94
|
+
end
|
95
|
+
|
96
|
+
it "opens the shell in that project" do
|
97
|
+
subject.run
|
98
|
+
expect(subject).to have_received(:exec).with("docker exec -it jupiter-saturn bash -c 'cd /var/code; TERM=xterm rails c'")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "returns true" do
|
102
|
+
expect(subject.run).to be_truthy
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "with an invalid project name" do
|
107
|
+
before do
|
108
|
+
subject.project_name = 'foo'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "logs an error" do
|
112
|
+
subject.run
|
113
|
+
expect(@log_entries).to eq [
|
114
|
+
"There is no project named foo"
|
115
|
+
]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns false" do
|
119
|
+
expect(subject.run).to be_falsey
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timecop'
|
3
|
+
|
4
|
+
describe RubyYacht::Runner::UpdateHosts do
|
5
|
+
include DockerCommandSpec
|
6
|
+
|
7
|
+
describe "command information" do
|
8
|
+
specify { expect(described_class.command).to eq 'update_hosts' }
|
9
|
+
specify { expect(described_class.description).to eq 'Add entries for your app domains to your hosts file' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "current_host_contents" do
|
13
|
+
it "is the contents of the hosts file" do
|
14
|
+
expect(subject.current_host_contents).to eq File.read('/etc/hosts')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "run behavior" do
|
19
|
+
before do
|
20
|
+
allow(subject).to receive("current_host_contents").and_return(<<-EOS.gsub(/^ +/, '')
|
21
|
+
# Local information
|
22
|
+
127.0.0.1 localhost
|
23
|
+
|
24
|
+
# Database server
|
25
|
+
|
26
|
+
40.1.30.10 db1.test.com
|
27
|
+
EOS
|
28
|
+
)
|
29
|
+
|
30
|
+
allow(subject).to receive("get_machine_info").with('.Driver.IPAddress').and_return('192.168.1.27')
|
31
|
+
Timecop.freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
FileUtils.rm(File.join('tmp', 'hosts'))
|
36
|
+
Timecop.return
|
37
|
+
end
|
38
|
+
|
39
|
+
it "adds the entries to the hosts file in the tmp folder" do
|
40
|
+
subject.run
|
41
|
+
expect(File.exist?(File.join('tmp', 'hosts'))).to be_truthy
|
42
|
+
|
43
|
+
contents = File.read(File.join('tmp', 'hosts'))
|
44
|
+
expect(contents).to eq <<-EOS.gsub(/^ +/, '').strip
|
45
|
+
# Local information
|
46
|
+
127.0.0.1 localhost
|
47
|
+
|
48
|
+
# Database server
|
49
|
+
|
50
|
+
40.1.30.10 db1.test.com
|
51
|
+
|
52
|
+
# apollo docker containers
|
53
|
+
192.168.1.27 apollo.test.com
|
54
|
+
192.168.1.27 mars.apollo.test.com
|
55
|
+
192.168.1.27 saturn.apollo.test.com
|
56
|
+
EOS
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
it "copies the hosts file to a backup, and the tmp hosts file to the hosts file" do
|
61
|
+
timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
|
62
|
+
subject.run
|
63
|
+
expect(@system_commands).to eq ["sudo cp /etc/hosts /etc/hosts.#{timestamp}.backup", "sudo mv tmp/hosts /etc/hosts"]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns true" do
|
67
|
+
expect(subject.run).to be_truthy
|
68
|
+
end
|
69
|
+
|
70
|
+
context "with existing entries in the hosts file" do
|
71
|
+
before do
|
72
|
+
allow(subject).to receive("current_host_contents").and_return(<<-EOS.gsub(/^ +/, '')
|
73
|
+
# Local information
|
74
|
+
127.0.0.1 localhost
|
75
|
+
|
76
|
+
# Database server
|
77
|
+
|
78
|
+
40.1.30.10 db1.test.com
|
79
|
+
|
80
|
+
# apollo docker containers
|
81
|
+
192.168.1.24 apollo.test.com
|
82
|
+
192.168.1.24 mars.apollo.test.com
|
83
|
+
192.168.1.24 venus.apollo.test.com
|
84
|
+
EOS
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "replaces the existing entries with the correct entries" do
|
89
|
+
subject.run
|
90
|
+
|
91
|
+
contents = File.read(File.join('tmp', 'hosts'))
|
92
|
+
expect(contents).to eq <<-EOS.gsub(/^ +/, '').strip
|
93
|
+
# Local information
|
94
|
+
127.0.0.1 localhost
|
95
|
+
|
96
|
+
# Database server
|
97
|
+
|
98
|
+
40.1.30.10 db1.test.com
|
99
|
+
|
100
|
+
# apollo docker containers
|
101
|
+
192.168.1.27 apollo.test.com
|
102
|
+
192.168.1.27 mars.apollo.test.com
|
103
|
+
192.168.1.27 saturn.apollo.test.com
|
104
|
+
EOS
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context "with no address from docker machine" do
|
109
|
+
before do
|
110
|
+
allow(subject).to receive("get_machine_info").with('.Driver.IPAddress').and_return('')
|
111
|
+
end
|
112
|
+
|
113
|
+
it "points the domains to localhost" do
|
114
|
+
subject.run
|
115
|
+
|
116
|
+
contents = File.read(File.join('tmp', 'hosts'))
|
117
|
+
expect(contents).to eq <<-EOS.gsub(/^ +/, '').strip
|
118
|
+
# Local information
|
119
|
+
127.0.0.1 localhost
|
120
|
+
|
121
|
+
# Database server
|
122
|
+
|
123
|
+
40.1.30.10 db1.test.com
|
124
|
+
|
125
|
+
# apollo docker containers
|
126
|
+
127.0.0.1 apollo.test.com
|
127
|
+
127.0.0.1 mars.apollo.test.com
|
128
|
+
127.0.0.1 saturn.apollo.test.com
|
129
|
+
EOS
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "with multiple projects" do
|
134
|
+
before do
|
135
|
+
RubyYacht.configure_second_test_project
|
136
|
+
end
|
137
|
+
|
138
|
+
it "creates entries for both projects" do
|
139
|
+
subject.run
|
140
|
+
|
141
|
+
contents = File.read(File.join('tmp', 'hosts'))
|
142
|
+
expect(contents).to eq <<-EOS.gsub(/^ +/, '').strip
|
143
|
+
# Local information
|
144
|
+
127.0.0.1 localhost
|
145
|
+
|
146
|
+
# Database server
|
147
|
+
|
148
|
+
40.1.30.10 db1.test.com
|
149
|
+
|
150
|
+
# apollo docker containers
|
151
|
+
192.168.1.27 apollo.test.com
|
152
|
+
192.168.1.27 mars.apollo.test.com
|
153
|
+
192.168.1.27 saturn.apollo.test.com
|
154
|
+
|
155
|
+
# jupiter docker containers
|
156
|
+
192.168.1.27 jupiter.test.com
|
157
|
+
192.168.1.27 venus.jupiter.test.com
|
158
|
+
192.168.1.27 saturn.jupiter.test.com
|
159
|
+
EOS
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/spec/spec_helper.rb
ADDED